<?php

	/* SVN FILE: $Id: functions.php 16 2011-03-14 20:57:11Z michele.andreoletti@gmail.com $ */
	
	/**
	 * Project Name : arcadia
	 *
	 * @author $Author: michele.andreoletti@gmail.com $
	 * @version $Revision: 16 $
	 * @lastrevision $Date: 2011-03-14 20:57:11 +0000 (Mon, 14 Mar 2011) $
	 * @filesource $URL: http://arcadia.googlecode.com/svn/trunk/include/functions.php $
	 */

	date_default_timezone_set('Europe/Rome');

	/**
	 * Criteri utilizzati per identificare il tipo di contenuto in una variabile a partire dal nome
	 *
	 * sValue --> string
	 * iValue --> int
	 * bValue --> boolean
	 * aValue --> array
	 * oValue --> object
	 * mValue --> mixed
	 *
	 * dtValue --> DATE (usato in MySQL)
	 * tsValue --> TIMESTAMP (usato in MySQL)
	 *
	 */

	include('fnLogin.php');
	include('fnInputs.php'); // contiene tutte le funzioni *Input (txtInput, calInput, etc.)
	include('fnTags.php');
	include('fnUploads.php');


	/**
	 * 
	 * fnFieldAccessLvl
	 *
	 * Determina i permessi di accesso al campo ($sField), al tab ($iTab) o a viewitemLink ($sViewItemLink),
	 * controllando i valori memorizzati nella variabile $_SESSION.
	 *
	 * Viene restituito il valore associato a $sField (se esiste), oppure quello associato a $iTab
	 * (se esiste), oppure quello associato a $sViewItemLink (se esiste), oppure $iAccessLvl. La
	 * priorità è stabilita sulla base dell'ordine indicato nella frase precedente ($sField ha la
	 * precedenza su $iTab, che a sua volta ha la precedenza su $sViewItemLink, che ha infine la precedenza
	 * su $iAccessLvl)
	 *
	 * Qualora durante l'esecuzione della funzione venga assegnato il valore -1 a $iFieldAccessLvl
	 * questo valore ha la precedenza su tutti gli eventuali valori assegnabili successivamente
	 * (ovvero: $iFieldAccessLvl rimane comunque uguale a -1).
	 * 
	 * NOTA: -1 è il valore che ha il significato di 'accesso negato'.
	 *
	 */	 
	function fnFieldAccessLvl($iAccessLvl, $sViewItemLink='', $iTab=0, $sField='') {

		// default: $iFieldAccessLvl è ugule a $iAccessLvl
		$iFieldAccessLvl = $iAccessLvl;
		
		// sViewItemLink
		if (!empty($sViewItemLink) && !is_null(fnGetAccessLvl('viewitemlink', array('sViewItemLink' => $sViewItemLink)))) {
			if ($iFieldAccessLvl != -1)
				$iFieldAccessLvl = fnGetAccessLvl('viewitemlink', array('sViewItemLink' => $sViewItemLink));
		}
		
		// iTab
		if (!empty($iTab) && is_numeric($iTab) && !is_null(fnGetAccessLvl('tab', array('sViewItemLink' => $sViewItemLink, 'sTab' => $iTab)))) {
			if ($iFieldAccessLvl != -1)
				$iFieldAccessLvl = fnGetAccessLvl('tab', array('sViewItemLink' => $sViewItemLink, 'sTab' => $iTab));
		}
		
		// sField
		if (!empty($sField) && !is_null(fnGetAccessLvl('field', array('sViewItemLink' => $sViewItemLink, 'sTab' => $iTab, 'sField' => $sField)))) {
			if ($iFieldAccessLvl != -1)
				$iFieldAccessLvl = fnGetAccessLvl('field', array('sViewItemLink' => $sViewItemLink, 'sTab' => $iTab, 'sField' => $sField));
		}

		return $iFieldAccessLvl;
	
	}
	
	
	/**
  	 *
  	 * fnButtons
  	 *
  	 */
  	function fnButtons ($iView, $iTab, $iAccessLvl, $aData) {
		
		global $sAction;
		
		global $bSEARCH_FORM_SHOW;
		
		$sViewItemLink = fnCurrentScript();
		
		global $aVIEW;
		$iTabDefault = $aVIEW[$sViewItemLink]['iTabDefault'];
		$bTagsShow = $aVIEW[$sViewItemLink]['bTagsShow'];

		$sButtons = '';

		if (empty($iView) || empty($aData['iTrash']))  {
			
			if ($sAction == 'edit')  {
				
				if (!empty($iView)) {
					$sActionTransact = 'update';
				} else if (empty($iView)) {
					$sActionTransact = 'insert';
				}
				
				if (is_allowed('edit', fnFieldAccessLvl($iAccessLvl, $iTab))) {
					// pulsante 'Salva'
					$sButtons .= "	<input type='hidden' name='iView' value='$iView'>";
					$sButtons .= "	<input type='hidden' name='sViewItemLink' value='$sViewItemLink'>";
					$sButtons .= "	<input type='hidden' name='iTab' value='$iTab'>";
					$sButtons .= "	<input type='hidden' name='sAction' value='$sActionTransact'>";
					$sButtons .= "	<input type='submit' value='Salva'>";
					$sButtons .= "</form>";	
					
					// pulsante 'Annulla'
					$sButtons .= "<div style='clear:both'></div>";
					$sButtons .= "<div style='float:left; margin-top: 5px;'>
									<form name='cancel' class='buttons' method='get' action='".(empty($iView) ? 'index.php' : $sViewItemLink)."'>";
					if ($iView == 0) {
						$sButtons .= fnHtmlBacklinkFull('input', '', $bSEARCH_FORM_SHOW, $bTagsShow);
					} else {
						$sButtons .= "	<input type='hidden' name='iView' value='$iView'>";
						$sButtons .= "	<input type='hidden' name='iTab' value='$iTab'>";
						$sButtons .= "	<input type='hidden' name='sAction' value='view'>";
					}
					$sButtons .= "		<input type='submit' value='Annulla'>";	
					$sButtons .= "	</form>";
					$sButtons .= "</div>";					
				}
				
			} else {
				
				if (is_allowed('edit', fnFieldAccessLvl($iAccessLvl, $iTab))) {
					// pulsante 'Modifica'
					$sButtons .= "<form name='edit' class='buttons' method='get' action='$sViewItemLink' style='float:left'>";
					$sButtons .= "	<input type='hidden' name='iView' value='$iView'>";
					$sButtons .= "	<input type='hidden' name='iTab' value='$iTab'>";
					$sButtons .= "	<input type='hidden' name='sAction' value='edit'>";
					$sButtons .= "	<input type='submit' value='Modifica'>";	
					$sButtons .= "</form>";
				}
				
				if ($iView != 0 && $iTab==$iTabDefault && is_allowed('delete', $iAccessLvl)) {
					// pulsante 'Elimina'
					// Non viene visualizzato nella scheda se si sta creando una nuova scheda ($iView == 0)
					// Viene visualizzato solo sul primo tab ($iTab == $iTAB_DEFAULT)
					$sButtons .= "<div style='clear:right'></div>";
					$sButtons .= "	<form name='trashverify' class='buttons' method='post' action='transact.php' style='float:right;'>";
					$sButtons .= "	<input type='hidden' name='iView' value='$iView'>";
					$sButtons .= "	<input type='hidden' name='sViewItemLink' value='$sViewItemLink'>";
					$sButtons .= "	<input type='hidden' name='iTab' value='$iTab'>";
					$sButtons .= "	<input type='hidden' name='sAction' value='trash-verify'>";
					$sButtons .= "	<input type='submit' value='Elimina'>";				
					$sButtons .= "</form>";
				}
				
			}
		
		} else if (!empty($aData['iTrash']))  {
			if (is_allowed('delete', $iAccessLvl)) {
				// pulsante 'Ripristina'
				$sButtons .= "<form name='restore' class='buttons' method='post' action='transact.php' style='float:left'>";
				$sButtons .= "	<input type='hidden' name='iView' value='$iView'>";
				$sButtons .= "	<input type='hidden' name='sViewItemLink' value='$sViewItemLink'>";
				$sButtons .= "	<input type='hidden' name='sAction' value='restore'>";
				$sButtons .= "	<input type='submit' value='Ripristina'>";	
				$sButtons .= "</form>";
			}
			
			if (is_allowed('sysop', $iAccessLvl)) {
				// pulsante 'Elimina Definitivamente'
				$sButtons .= "<div style='clear:right'></div>";
				$sButtons .= "<form name='delverify' class='buttons' method='post' action='transact.php' style='float:right;'>";
				$sButtons .= " <input type='hidden' name='iView' value='$iView'>";
				$sButtons .= " <input type='hidden' name='sViewItemLink' value='$sViewItemLink'>";
				$sButtons .= " <input type='hidden' name='sAction' value='purge-verify'>";
				$sButtons .= " <input type='submit' value='Elimina Definitivamente'>";				
				$sButtons .= "</form>";
			}
		} 
		return $sButtons;
	}


	/**
	 * 
	 * custom_mysql_query
	 *
	 */	 
	 function custom_mysql_query ($sQuery, $sText='') {
		$rResult = mysql_query($sQuery);
		if (!$rResult) {
			die(	!fnShowDebugMsg() ?
					"<div style='width:80%; height:5em;'>".
						"<b>MySQL ERROR $sText</b></br>".
						mysql_error()."</br>".
						"<textarea style='margin-top:1em; width:100%; height:10em;'>".$sQuery."</textarea>".
						"</div>" :
					"<b>MySQL ERROR $sText</b>"
				);	
		}
		
		return $rResult;		
	}
	
	
	/**
	 * 
	 * fnGetDataFromQuery
	 *
	 */	 
	function fnGetDataFromQuery ($sQuery, $sText='') {
		$aData = array();	
		$rResult = custom_mysql_query($sQuery, $sText);
		if (mysql_num_rows($rResult)>0) {
			while ($aRow = mysql_fetch_assoc($rResult)) {
				$aData[] = $aRow;	
			}
		}
		return $aData;	
	}
	
	
	/**
	 * 
	 * fnQueryDeleteFromTrash
	 * 
	 * Cancella dal cestino (ovvero i record per cui iTrash == 1)
	 *
	 */	 
	function fnQueryDeleteFromTrash ($sFormTable, $sViewSelectFrom, $iView=0, $iMaxDaysInTrash=0) {
		
		global $sAPP;
		
		$sQuery = "DELETE FROM `$sFormTable`, `uploads`, `uploads_bin`, `tags`
							USING `$sFormTable`
							LEFT OUTER JOIN `uploads` ON `uploads`.`iView` = `$sFormTable`.`id` AND `uploads`.`sSelectFrom` = '$sViewSelectFrom' AND `uploads`.`sApp` = '$sAPP' 
							LEFT OUTER JOIN `uploads_bin` ON `uploads_bin`.`iUpload` = `uploads`.`id`
							LEFT OUTER JOIN `tags` ON `tags`.`iView` = `$sFormTable`.`id` AND `tags`.`sSelectFrom` = '$sViewSelectFrom' AND `tags`.`sApp` = '$sAPP'";
							
		if (!empty($iView)) {
				// cancella un record dal cestino
			$sQuery .= " WHERE `$sFormTable`.`iTrash` = '1' AND `$sFormTable`.`id` = '$iView'";
		
		} else if (empty($iView) && !empty($iMaxDaysInTrash)) {
				// cancella tutti i dati 'vecchi' dal cestino
			$sQuery .= " WHERE `$sFormTable`.`iTrash` = '1' AND DATEDIFF(CURRENT_DATE, `$sFormTable`.`tsTrashWhen`) > '$iMaxDaysInTrash'";
		
		} else if (empty($iView) && empty($iMaxDaysInTrash)) {
				// cancella tutti i dati dal cestino
			$sQuery .= " WHERE `$sFormTable`.`iTrash` = 1";
		
		}

		return $sQuery;		
	}
	
	
	/**
	 * 
	 * fnCheckView
	 * Verifica che esista, nella tabella `$sViewSelectFrom` un record con `id` = $iView ".
	 *
	 * In caso di verifica positiva restituisce un array contenente i campi della tabella 
	 * `$sViewSelectFrom` relativi al record $iView.
	 *
	 * Nel caso in cui $sReturnWhat == 'bError' la funzione ritorna 'false' se $iView esiste, mentre
	 * restituisce 'true' se $iView non esiste. Funziona al contrario di come ci si aspetterebbe
	 * perchè segnala quando c'è un errore.
	 *
	 * Questa funzione è utilizzata in view.php, transact.php, tagging.php, etc. etc.
	 *
	 */
	function fnCheckView ($iView, $sViewSelectFrom, $sViewSelectGroupby, $sReturnWhat='aData') {
		
		$sQuery = fnCheckViewQuery($iView, $sViewSelectFrom, $sViewSelectGroupby);
		$rResult = custom_mysql_query($sQuery, 'fnCheckViewQuery()');
		
		if (mysql_num_rows($rResult) != 1) {
			if ($sReturnWhat == 'bError') {
				$bError = true; // iView non esiste... quindi $bError è 'true'
				return $bError;
				
			} else if ($sReturnWhat == 'aData' || true) { // di default la funzione restituisce  un array (in questo caso vuoto)
				return array();
				
			} 	

		} else if (mysql_num_rows($rResult) == 1) {
			if ($sReturnWhat == 'bError') {
				$bError = false; // iView esiste... quindi $bError è 'false'
				return $bError;
				
			} else if ($sReturnWhat == 'aData' || true) { // di default la funzione restituisce un array
				$aRow = mysql_fetch_assoc($rResult);
				return $aRow;
				
			}

		}		
	}


	/**
	 *
	 * fnCheckViewTrashed
	 * Restituisce true se il record identificato da $iView è nel cestino (iTrash==1), altrimenti
	 * restituisce false.
	 *
	 */
	function fnCheckViewTrashed ($iView, $sViewSelectFrom, $sViewSelectGroupby) {
		$aData = fnCheckView ($iView, $sViewSelectFrom, $sViewSelectGroupby, 'aData');
		if (isset($aData['iTrash']) && !empty($aData['iTrash']))
			return true;
		else
			return false;
	}
	
	
	/**
	 *
	 * fnCheckViewQuery
	 *
	 */	
	function fnCheckViewQuery ($iView, $sViewSelectFrom, $sViewSelectGroupby) {
		$sQuery = "SELECT * FROM `$sViewSelectFrom` WHERE `id` = $iView ";
		if ($sViewSelectGroupby != '') {
			$sQuery .= " GROUP BY `$sViewSelectGroupby` "; 			
	  	}
	  	return $sQuery;
	}	


	/**
	 * 
	 * fnHtmlBackButton
	 * Restituisce un form con un bottone per ritornare alla tabella 'main-table' conservando i
	 * vari parametri di visualizzazione della tabella (sTable, sSearchTerms, sTag, etc. etc)
	 *
	 */
	function fnHtmlBackButton($bSHOW_SEARCHFORM, $bSHOW_TAGS, $aTABLE) { 
		
		global $sAPP;

		$sLabel = "Indietro";
		if (!is_null(fnReadSessionValue('sTable', 'main-table', $sAPP))) { 
			if (isset($aTABLE[fnReadSessionValue('sTable', 'main-table', $sAPP)])) {
			$sTable =  fnReadSessionValue('sTable', 'main-table', $sAPP);
			$sLabel = $aTABLE[$sTable]['sTableName'];	
			}
		}
		$html  = "<form class='buttons small-text' method='get' action='index.php' style='margin-top: 12px;'>"; // FIXME: Le info sullo stile dovrebbero andare in un file .css
		$html .= fnHtmlBacklinkFull('input', '', $bSHOW_SEARCHFORM, $bSHOW_TAGS);
		$html .= "<button style='width:100%' type='submit'>".strip_tags($sLabel)."</button></form>"; // FIXME: Le info sullo stile dovrebbero andare in un file .css
		return $html;
	}
	
	
	/**
	 *
	 * br2space
	 *
	 */
	 function br2space ($sInput) {
		 $sOutput = str_replace( "<br>", " ", $sInput );
		 $sOutput = str_replace( "<br/>", " ", $sOutput );
		 $sOutput = str_replace( "<br />", "  ", $sOutput );
		 $sOutput = str_replace( "<BR>", " ", $sOutput );
		 $sOutput = str_replace( "<BR/>", " ", $sOutput );
		 $sOutput = str_replace( "<BR />", " ", $sOutput );
		 return $sOutput;
	}



	/**
	 *
	 * fnGetResourcesQuery
	 *
	 */
	 function fnGetResourcesQuery ($sType, $aFields=array(), $sShow='') {
		
		// $sShow == 1 -- solo risorse 'visibili'
		// $sShow == 0 -- solo risorse 'invisibili'
		// $sShow == '' -- tutte le risorse (sia visibili che invisibility)
		
		switch ((string)$sShow) {
			case '1':
			case '0':
				$sShow = " AND `iShow`='$sShow' ";
				break;
			default:
				$sShow = '';
				break;
		}
		
		$sValues = "`resources`.*";
		$sJoin = '';
		
		if (!empty($aFields)) {
			foreach ($aFields as $sField) {
				$sJoin .= "	LEFT OUTER JOIN `properties` `$sField` on `$sField`.`iTable` = `resources`.`id`
					AND `$sField`.`sSelectFrom` = 'resources' AND `$sField`.`sField` = '$sField'	";
				$sValues .= ", `$sField`.`sValue` AS `$sField` ";
			}
		}
		
		$sQuery = "	SELECT $sValues FROM `resources` $sJoin WHERE `sType` = '$sType' $sShow ORDER BY `sDescription`";
		return $sQuery;
		
	}


	/**
	 *
	 * fnGetResourceProperties
	 *
	 */
	function fnGetResourceProperties ($iResource, $mWhat, $sType) {
		
		if (is_array($mWhat)) {
			
			$sSelect = $sJoin = '';
			
			foreach ($mWhat as $sWhat) {
				$sSelect .= ", `$sWhat`.`sValue` AS `$sWhat` ";
				$sJoin .= " LEFT OUTER JOIN `properties` `$sWhat` ON  `$sWhat`.sSelectFrom='resources' AND `$sWhat`.`iTable`=`resources`.`id` AND `$sWhat`.`sField`='$sWhat' ";
			}
			
			$sQuery = "
				SELECT `id`, `sDescription` $sSelect FROM `resources`
				$sJoin
				WHERE `id`='$iResource' AND `sType`='$sType' ";
		
		} else if (is_string($mWhat)) {
			
			$sWhat = $mWhat;
			
			$sQuery = "
				SELECT `id`, `sDescription`, `$sWhat`.`sValue` AS `$sWhat` FROM `resources`
				LEFT OUTER JOIN `properties` `$sWhat` ON  `$sWhat`.sSelectFrom='resources' AND `$sWhat`.`iTable`=`resources`.`id` AND `$sWhat`.`sField`='$sWhat'
				WHERE `id`='$iResource' AND `sType`='$sType' ";
		
		} else {
		
			$sQuery = '';
			
		}


		if (!empty($sQuery)) {

			$rResult = custom_mysql_query($sQuery);
			
			if (mysql_num_rows($rResult) == 1) {
				
				$aData = mysql_fetch_assoc($rResult);
				
				if (is_array($mWhat)) {
					return $aData;
				
				} else if (is_string($mWhat) && isset($aData[$sWhat])) {
					return $aData[$sWhat];
				
				} else {
					return null;
				
				}	
			
			}
		
		}
		
		return null;
	}



	/**
	 * 
	 * fnEvaluateTablesAccessLvl ($aTableSecurityCheck, $bShowHidden)
	 * Elimina dall'array $aTABLE (definito in 'const.inc.php') ciò che l'utente non è autorizzato a
	 * visualizzare.
	 * 
	 * Inoltre elimina da $aTABLE ciò che è nascosto ($iShow == 0) nel caso in cui $bShowHidden abbia
	 * il valore 'false'.
	 * 
	 * Aggiunge, se $sTable è incluso nell'array $aTABLE_SECURITY_CHECK, le condizioni definite
	 * nella variabile $sTableSelectWhere di ciascun elenco $sTable alla stringa $sWhere.
	 * 
	 * @param string $aTableSecurityCheck	array $aEL_SECURITY_CHECK definito in const.inc.php;
	 * 										contiene l'elenco delle tabelle ($sTable) per cui
	 *										eseguire un controllo sul livello di accesso alle schede
	 *										appartenenti all'elenco.
	 *
	 * @param boolean $bShowHidden			indica se visualizzare o meno le tabelle nascoste, ovvero
	 *										quelle per cui iShow=0 (ad esempio quelle usate in
	 *										'budget' per 'report.php').
	 *
	 * @return null							questa funzione modifica direttamente le variabili
	 *										$aTABLE e $sWhere (entrambe richiamate come variabili
	 * 										'global').
	 */	 
	function fnEvaluateTablesAccessLvl ($aTableSecurityCheck, $bShowHidden=false) {
		
		global $sAPP;
		
		global $aTABLE;
		global $aWhere;
		
		foreach ($aTABLE as $sTable => $aTable) {
				
			if (!is_null(fnReadSessionValue($sTable, 'AccessLvl', $sAPP, 'table'))) {
				
				
				if (!is_allowed('view', fnReadSessionValue($sTable, 'AccessLvl', $sAPP, 'table'))) {
					
					if (in_array($sTable, $aTableSecurityCheck)) {
						// se non è autorizzata la visualizzazione, escludo dai risultati della
						// query tutti i record che appartengono all'elenco '$sTable'
						
						if (isset($aTable['sTableSelectFrom']) && isset($aTable['sTableSelectWhere'])) {
							$sTableSelectFrom= $aTable['sTableSelectFrom'];
							$sTableSelectWhere = $aTable['sTableSelectWhere'];
						} else  {
							die('ERROR: sTableSelectFrom or sTableSelectWhere not defined');
						}
						
						if (isset($aWhere[$sTableSelectFrom]['sTableSelectWhere']))
							$aWhere[$sTableSelectFrom]['sTableSelectWhere'] .= " AND NOT (".$sTableSelectWhere.") ";
						else
							$aWhere[$sTableSelectFrom]['sTableSelectWhere'] = " AND NOT (".$sTableSelectWhere.") ";
							
					}
					
					// se non è autorizzata la visualizzazione, elimino l'elenco '$sTable'
					// dall'array $aTABLE
					
					if (isset($aTABLE[$sTable])) { unset($aTABLE[$sTable]); }
					
				}

			}
		
		}

		if (!$bShowHidden) {
			foreach ($aTABLE as $sTable => $aValues) {
				
				if (isset($aTABLE[$sTable]['iShow'])) { $iShow = $aTABLE[$sTable]['iShow']; } 
				else  { $iShow = 0; }
				
				if ($iShow == 0) unset($aTABLE[$sTable]);
			
			}
		}

	}	


	/**
	 *
	 * fnSelectFilter
	 *
	 */
	function fnSelectFilter($sWhat, $aFilter, $sTable) { 
	
		$html = $sWhere = $sTableTitle = '';	
		$iMaxChar = 65; // massima lunghezza di una stringa di un campo <option>
		
		$sField = $aFilter['sField'];
		
		global $$aFilter['sField'];
		$sValue = $$aFilter['sField'];
		
		$sAlias = $aFilter['sAlias'];
		
		$sLabel = $aFilter['sLabel'];
		
		global $aTABLE;

		if (isset($aTABLE[$sTable]['sTableSelectFrom'])) {
			$sTableSelectFrom = $aTABLE[$sTable]['sTableSelectFrom'];
		} else  {
			die('ERROR: sTableSelectFrom not defined');
		}
		
		if (isset($aTABLE[$sTable]['sTableSelectWhere'])) {
			$sTableSelectWhere = $aTABLE[$sTable]['sTableSelectWhere'];
		} else  {
			die('ERROR: sTableSelectWhere not defined');
		}	
		
		$sQuery = " SELECT `$sField`, `$sAlias`
				FROM `$sTableSelectFrom`
				WHERE $sTableSelectWhere OR `$sField` = '$sValue'
				GROUP BY `$sAlias` HAVING `$sAlias` != ''
				ORDER BY `$sAlias`";
			
		$rResults = custom_mysql_query($sQuery, 'fnSelectFilter()');
		
		$html .= "<div class='input-label'>".$sLabel."</div><div class=''>";
		$html .= "<select name='$sField' id='$sField'>";
		$html .= "	<option value='' ".($sValue == '' ? ' selected' : '' ).">".
						(mysql_num_rows($rResults) == 0 ? "Selezione non disponibile" : "Seleziona $sLabel...").
				 "	</option>";
					
		if (mysql_num_rows($rResults) > 0) {
		
			while ($aRow = mysql_fetch_array($rResults)) {
				
				$html .= "<option value='".$aRow[$sField]."' ".($aRow[$sField] == $sValue ? ' selected' : '' ).">".
							(strlen($aRow[$sAlias])>$iMaxChar ? substr($aRow[$sAlias], 0, $iMaxChar-4)." (...)" : $aRow[$sAlias]).
						 "</option>";
				
				if (!empty($sValue) && $aRow[$sField] == $sValue) { 
					$sWhere .= " AND `$sField` = '$sValue' ";
				}
				 
			}
			
		}

		$html .= "</select>&nbsp;</div>";

		$sTableTitle = "<span class='table-title-more' id='$sAlias'> &raquo; <span class='table-title-value'></span></span>";

		/**
		 * il titolo verrà poi completato dal codice javascript della funzione 	$(document).ready(),
		 * che inserirà un testo all'interno dei <span class='table-title-value'> e stabilirà se
		 * <span class='table-title-more' id='table-title-$sAlias'> è da visualizzare o da tenere
		 * nascosto.
		 */

		switch ($sWhat) {
			case 'html':
				return $html;
				break;		
			case 'sTableTitle':
				return $sTableTitle;
				break;
			case 'sWhere':
				return $sWhere;
				break;		
			default:
				return array(	'html' => $html,
								'sTableTitle' => $sTableTitle,
								'sWhere' => $sWhere				);
				break;
		}

	}


	/**
	 *
	 * fnJsonOutput
	 * 
	 */
	function fnJsonOutput ($sScript, $sAction, $sHtml='', $iErrorCode=0, $aAdditionalVars=array()) {
	
		switch ($iErrorCode) {
		
			case 0: $sError = ''; // nessun errore
				break;
			
			case 100: $sError = 'Record id empty';
				break;
				
			case 101: $sError = 'Action not valid';
				break;
				
			case 102: $sError = 'Parameter not valid';
				break;
			
			case 111: $sError = 'Record not found';
				break;
				
			case 888: $sError = 'App not defined';
				break;
			
			case 999: $sError = 'Low rights';
				break;
			
			/* $bTagsShow */
			
			case 200: $sError = 'Tag id empty';
				break;
			
			case 222: $sError = 'Tag not found';
				break;
				
			/* Uploads */
			
			case 300: $sError = 'File id empty';
				break;
			
			case 333: $sError = 'File not found';
			
				break;			
			/* Sysop */
			
			case 444: $sError = 'Username not found';
				break;
			
			/* Email */
			
			case 505: $sError = 'Email error';
				break;
				
			/* Unknown */
			
			default: $sError = 'Unknown error';
				break;
		
		}
		
		$sAdditionalVars = '';
		if (!empty($aAdditionalVars)) {
			foreach ($aAdditionalVars as $sKey => $sValue) {
				$sAdditionalVars .= ", \"$sKey\": \"$sValue\"";
			}
		}
		
		if (!empty($sHtml)) {
			$sHtml = preg_replace("/\"/", "\\\"", $sHtml);
			$sHtml = preg_replace('/[\n\r\t]/','',$sHtml);
		}
		
		$sOutput = "[ { \"sScript\": \"$sScript\", \"sAction\": \"$sAction\", \"sHtml\": \"$sHtml\", \"sError\": \"$sError\" $sAdditionalVars } ]";
		
		return $sOutput;
		
	}


	/**
	 *
	 * array_to_json
	 *
	 */
	function array_to_json ($array) {
	
	    if (!is_array($array)) {
	        return false;
	    }
	
	    $associative = count(array_diff(array_keys($array), array_keys(array_keys($array))));
	    if ($associative) {
	        $construct = array();
	        foreach ($array as $key => $value) {
	            // We first copy each key/value pair into a staging array,
	            // formatting each key and value properly as we go.

	        	// Format the key:
	            if (is_numeric($key)) {
	                $key = "key_$key";
	            }
	            $key = "\"".addslashes($key)."\"";
	
	            // Format the value:
	            if (is_array($value)) {
	                $value = array_to_json($value);
	            } else if (!is_numeric($value) || is_string ($value)) {
	                $value = "\"".preg_replace("/\"/", "\\\"", $value)."\"";
	            }
	
	            // Add to staging array:
	            $construct[] = "$key: $value";
	        }
	        // Then we collapse the staging array into the JSON form:
	        $aResult = "{ " . implode( ", ", $construct ) . " }";
	
	    } else { // If the array is a vector (not associative):
	
	        $construct = array();
	        foreach ($array as $value) {
	
	            // Format the value:
	            if (is_array($value)){
	                $value = array_to_json($value);
	            } else if (!is_numeric($value) || is_string($value)){
	                $value = "\"".preg_replace("/\"/", "\\\"", $value)."\"";
	            }
	
	            // Add to staging array:
	            $construct[] = $value;
	        }
	        // Then we collapse the staging array into the JSON form:
	        $aResult = "[ " . implode( ", ", $construct ) . " ]";
	    }
	    return $aResult;
	}


	/**
	 *
	 * fnHtmlHiddenInputs
	 *
	 */
	function fnHtmlHiddenInputs ($bSearchFormShow, $bTagsShow, $sTable) {
		global $sSUITE_NAME, $sAPP;

		$sHiddenInputs = '';
		
		if ($bSearchFormShow) {
			$sName = 'sSearchTerms';
			$sValue = (!is_null(fnReadSessionValue($sName, 'main-table', $sAPP)) ? fnReadSessionValue($sName, 'main-table', $sAPP) : '');
				$sHiddenInputs .= "<input type='hidden' name='$sName' value=\"$sValue\">";	
		}
		
		if ($bTagsShow) {
			$sName = 'sTag';
			$sValue = (!is_null(fnReadSessionValue($sName, 'main-table', $sAPP)) ? fnReadSessionValue($sName, 'main-table', $sAPP) : '');
				$sHiddenInputs .= "<input type='hidden' name='$sName' value=\"$sValue\">";	
		}
		
		$aSelect = fnSettingsArray($sTable, 'select');
		if (sizeof($aSelect) > 0) {
			foreach ($aSelect as $aFilter) {
				$sName = $aFilter['sField'];
				$sValue = (!is_null(fnReadSessionValue($sName, 'main-table', $sAPP)) ? fnReadSessionValue($sName, 'main-table', $sAPP) : '');
					$sHiddenInputs .= "<input type='hidden' name='$sName' value=\"$sValue\">";	
			}
		}
		
		$aRadiob = fnSettingsArray($sTable, 'radiob');
		if (sizeof($aRadiob) > 0) {
			$sName = "sShow";
			$sValue = (!is_null(fnReadSessionValue($sName, 'main-table', $sAPP, $sTable)) ? fnReadSessionValue($sName, 'main-table', $sAPP, $sTable) : '');
					$sHiddenInputs .= "<input type='hidden' name='$sName' value=\"$sValue\">";	
		}
		
		// FIXME: mancano i parametri 'page', 'orderby', 'limit'... non li ho inseriti perchè non so
		// come fare ad aggiornarli dinamicamente quando cambia qualcosa nella tabella...
		
		return $sHiddenInputs;
	
	}	


   /**
	* fnLinks2Tables
	*
	* Funzione utilizzata in table.php per creare i link alle varie tabelle dell'applicazione
	* il risultato di questa funzione viene memorizzato nella variabile $sSidebar
	*
	*/
	function fnLinks2Tables ($sTable, $bSearchFormShow, $bTagsShow)  {
		
		global $aTABLE;
		
		global $sJsDocumentReady;
		
		$html = '';
		$sSidebarForm = '';
		
		foreach ($aTABLE as $sKey => $aValues)  {
			foreach ($aValues as $sVar => $sValue) {
				$$sVar = $sValue;
			}
	
			if ($sTableName == 'spacer') {
				
				$html .= "	<dd>&nbsp;</dd>";
				
			 } else {
			 
				$html .= "	<dd>
								<a id='sidebar-link-".$sKey."' ".($sTable == $sKey ? " class='selected' " : "")." href='#'>
									<img alt='$sTableName' src='images/$sTableIcon' />
									$sTableName
								</a>
							</dd> ";
			
				$sSidebarForm .= "<form class='sidebar-form' id='sidebar-form-".$sKey."' action='index.php'>
										<input type='hidden' name='sTable' value='$sKey'>";
										if ($sKey != $sTable)  {
											$sSidebarForm .= fnHtmlHiddenInputs($bSearchFormShow, $bTagsShow, $sKey);
										}
				$sSidebarForm .= "</form>";
		
				$sJsDocumentReady .= "$('#sidebar-link-".$sKey."').click(function() { $('#sidebar-form-".$sKey."').submit(); });"; 
			
			}
		
		}
		
		$html .= $sSidebarForm;
		
		/** 
		 * ho creato la variabile $sSidebarForm e l'ho aggiunta, solo alla fine, a $html perchè
		 * altrimenti inserendo i form tra un <dd> ed il successivo diversi browser lasciano troppo
		 * spazio ed il risultato non è esteticamente bello.
		 *
		 */
		 
		return $html;
	}


	/**
	 *
	 * fnSuiteAppsLinks()
	 * Questa funzione serve per generare il codice html della pagina principale del menu
	 ($sWhat='springboard) oppure per
	 */
	 
	function fnSuiteAppsLinks ($sWhat='menu') {
		
		global $aSUITE;
		global $sTHEME;
		
		$sCurrentApp = whichApp();
		
		$sSCRIPT_ROOT_PATH = (fnIsScriptInRoot() ? '.' : '..');
		
		$html = '';

		foreach ($aSUITE as $sApp => $aValues) {
			
			foreach ($aValues as $sKey => $sValue) {
				$$sKey = $sValue;
			}
			
			if (is_allowed('view', fnGetAppAccessLvl($sApp))) {

				if ($sWhat == 'menu') {
					$html .= "<li><a
						class='".(is_allowed('sysop', fnGetAppAccessLvl($sApp)) && ($sCurrentApp == $sApp) ? 'parent' : '')."'
						href='$sSCRIPT_ROOT_PATH/$sApp'><span>$sAPP_NAME</span></a>";
					
					if (is_allowed('sysop', fnGetAppAccessLvl($sApp)) && ($sCurrentApp == $sApp)) {
						$html .= "<ul>";
						$html .= "	<li><a href='$sSCRIPT_ROOT_PATH/$sApp/settings.php'><span>Impostazioni</span></a></li>";
						$html .= "	<li><a href='$sSCRIPT_ROOT_PATH/$sApp/security.php'><span>Gestione Accessi</span></a></li>";
						$html .= "	<li><a href='$sSCRIPT_ROOT_PATH/$sApp/const.php'><span>Variabili di Sistema</span></a></li>";
						$html .= "</ul>";
					}
					
					$html .= "</li>";

				} else if ($sWhat == 'springboard') { 
					$html .= "<div class='springboard'>";
					$html .= "	<a href='$sSCRIPT_ROOT_PATH/$sApp'><img class='icon-large' src='themes/common/images/$sAPP_IMG' /></a>";	
					$html .= "	<h1><a href='$sApp'>$sAPP_NAME</a>";
					
					if (is_allowed('sysop', fnGetAppAccessLvl($sApp))) {
						$html .= "	&nbsp;<a href='$sSCRIPT_ROOT_PATH/$sApp/settings.php'><img class='icon-small' src='$sSCRIPT_ROOT_PATH/themes/$sTHEME/images/preferences-small.png' /></a>";
						$html .= "	&nbsp;<a href='$sSCRIPT_ROOT_PATH/$sApp/security.php'><img class='icon-small' src='$sSCRIPT_ROOT_PATH/themes/$sTHEME/images/lock-small.png' /></a>";
						$html .= "	&nbsp;<a href='$sSCRIPT_ROOT_PATH/$sApp/const.php'><img class='icon-small' src='$sSCRIPT_ROOT_PATH/themes/$sTHEME/images/terminal-small.png' /></a>";
					}
					
					$html .= "	</h1>";
					$html .= "	<p>$sAPP_TEXT</p>";
					$html .= "	<div class='spacer'></div>";
					$html .= "</div>";
					
				}
				
			}
			
		}
		
		return $html;
	
	}


	/**
	 *
	 * fnTableConst
	 * Variabili relative a $sTable, definite in $aTABLE (const.inc.php).
	 *
	 */
	function fnTableConst ($sTable) {
		
		global $aTABLE;

		if (isset($aTABLE[$sTable])) {
			foreach ($aTABLE[$sTable] as $sKey => $sValue) {
				global $$sKey;
				$$sKey = $sValue;
			}	
		}
		
		if (isset($sTableSelectWhere)) {
			$sTableSelectWhere = str_replace('_USERNAME_', fnReadSessionValue('sUsername'), $sTableSelectWhere);
		}

	}


	/**
	 *
	 * fnViewConst
	 * Variabili relative a $sViewItemLink, definite in $aVIEW (const.inc.php).
	 *
	 */
	function fnViewConst ($sViewItemLink) {
		
		global $aVIEW;

		if (isset($aVIEW[$sViewItemLink])) {
			foreach ($aVIEW[$sViewItemLink] as $sKey => $sValue) {
				global $$sKey;
				$$sKey = $sValue;
			}	
		} 
	}


	/**
	 *
	 * fnOnly4Sysop()
	 * Se è specificato $sApp la funzione verifica se l'utente è amministratore di sistema (iSysop=1)
	 * oppure di un'applicazione (iAccessLvl=9). Se non è specificato $sApp la funzione verifica se
	 * l'utente è amministratore di sistema (iSysop=1).
	 *
	 * Nel caso in cui l'utente non sia un sysop interrompe l'esecuzione dello script con un die(),
	 * oppure, nel caso in cui $sOutput == 'json', prima del die() esegue fnJsonOutput().
	 *
	 */
	 
	 function fnOnly4Sysop ($sApp='', $sOutput='') {
		
		global $aTABLE;
		
		$iAccessLvl = 0;
		$sScript = fnCurrentScript();
		$sSCRIPT_ROOT_PATH = (fnIsScriptInRoot() ? '.' : '..');
		
		if (!empty($sApp) && isset($aTABLE[$sApp])) {
			$iAccessLvl = fnGetAppAccessLvl($sApp);
		}
		
		if (!is_allowed('sysop', $iAccessLvl)) {
			fnUpdateLog('LOW RIGHTS', 0, '','S');
			
			if ($sOutput == 'json') {
				echo fnJsonOutput($sScript, $sAction, '', 999);
				die();
			
			} else {
				header("Location: $sSCRIPT_ROOT_PATH/index.php?sMsg=low-rights");
				die();
			
			}
		
		}
	}





	/**
	 * 
	 * fnUpdateLog
	 * Aggiorna la tabella `log`.
	 * Cancella dalla tabella `log` tutti i record più vecchi del numero di giorni specificato da
	 * $iMAX_DAYS_IN_LOG.
	 *
	 * $sType:	'I' info >> general messages
	 *			'E' error >> error messages
	 *			'S' security >> security & iAccessLvl related messages
	 *
	 */
	function fnUpdateLog ($sDescription, $mView=0, $sSelectFrom='', $sType='I') {
	
		global $sSUITE_NAME;
		global $sAPP;
		
		$sRemoteAddr = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '');
		
		$sScript = fnCurrentScript();
		
		if (!isset($_SESSION)) { session_start(); }
		
		$sUsername = (!is_null(fnReadSessionValue('sUsername')) ? fnReadSessionValue('sUsername') : '');
		
		$sApp = (isset($sAPP) && !empty($sAPP) ? $sAPP : $sSUITE_NAME);
		
		$sQuery = fnUpdateLogQuery($sRemoteAddr, $sDescription, $sScript, $sType, $sUsername, $mView, $sSelectFrom, $sApp);
		$rResult = custom_mysql_query($sQuery, 'fnUpdateLogQuery()'); 
		
		global $iMAX_DAYS_IN_LOG;
		
		if (isset($iMAX_DAYS_IN_LOG) && $iMAX_DAYS_IN_LOG > 0) {
			$sQuery = fnQueryCleanLog($iMAX_DAYS_IN_LOG);
			$rResult = custom_mysql_query($sQuery, 'fnQueryCleanLog()');
		}
		
	}


	/**
	 *
	 * fnUpdateLogQuery
	 * 
	 * $mView può essere una variabile di tipo integer oppure un array contenente variabili di tipo
	 * integer.
	 * 
	 */
	 function fnUpdateLogQuery ($sRemoteAddr, $sDescription, $sScript, $sType, $sUsername, $mView, $sSelectFrom, $sApp) {
		
		$sValues = '';
		
		if (is_array($mView) && !empty($mView)) {
			foreach ($mView as $iView) {
				if (is_numeric($iView) && $iView > 0) { 
					$sValues .= "('$sRemoteAddr', '$sDescription', '$sScript', '$sType', '$sUsername', '$iView', '$sSelectFrom', '$sApp'), ";
				
				} else { 
					$sValues .= "('$sRemoteAddr', '$sDescription', '$sScript', '$sType', '$sUsername', '0', '$sSelectFrom', '$sApp'), ";
				
				}
			}
			$sValues = substr($sValues, 0, -2);
		
		} else {
			if (is_numeric($mView) && $mView > 0) { 
				$sValues .= "('$sRemoteAddr', '$sDescription', '$sScript', '$sType', '$sUsername', '$mView', '$sSelectFrom', '$sApp')";
			
			} else { 
				$sValues .= "('$sRemoteAddr', '$sDescription', '$sScript', '$sType', '$sUsername', '0', '$sSelectFrom', '$sApp')";
				
			}
		
		}
		
		$sQuery = "
			INSERT INTO `log` (`sRemoteAddr`, `sDescription`, `sScript`, `sType`, `sUsername`, `iView`, `sSelectFrom`, `sApp`)
			VALUES $sValues";
			
		return $sQuery;

	}


	/**
	 * 
	 * fnQueryLog
	 *
	 */ 
	function fnQueryLog () {
		$sQuery = " SELECT * FROM `log` ORDER BY `tsWhen` DESC ";
		return $sQuery;
	}		


	/**
	 * 
	 * fnQueryCleanLog
	 * Cancella dalla tabella `log` tutti i record più vecchi del numero di giorni specificato dal
	 * parametro $iDays.
	 */ 
	function fnQueryCleanLog ($iDays) {
		$sQuery = "	DELETE FROM `log` WHERE DATEDIFF(CURDATE(),`tsWhen`) > $iDays ";
		return $sQuery;	
	}


	/**
	 *
	 * print_nice()
	 * Federico Bricker 29-Jun-2009 11:02
	 * Here is a nice version of print_r that prints things with colors and tables.
	 * I've called it print_nice 
	 * http://php.net/manual/en/function.print-r.php
	 *
	 */	 
	function print_nice ($mElem, $iMaxLevel=10, $aPrintNiceStack=array()) {
		
		$sOutput = '';
		
		if(is_array($mElem) || is_object($mElem)){
			
			if(in_array(&$mElem, $aPrintNiceStack, true)){
				$sOutput .= "<font color=red>RECURSION</font>";
				return $sOutput;
			}
			
			$aPrintNiceStack[]=&$mElem;
			
			if ($iMaxLevel<1) {
				$sOutput .= "<font color=red>nivel maximo alcanzado</font>";
				return $sOutput;
			}
			
			$iMaxLevel--;
			
			$sOutput .= "<table border=1 cellspacing=0 cellpadding=3 width=100%>";
			
			if (is_array($mElem)) {
				$sOutput .= '<tr><td colspan=2 style="background-color:#333333;"><strong><font color=white>ARRAY</font></strong></td></tr>';

			} else {
				$sOutput .= '<tr><td colspan=2 style="background-color:#333333;"><strong>';
				$sOutput .= '<font color=white>OBJECT Type: '.get_class($mElem).'</font></strong></td></tr>';
			}
			
			$color=0;
			
			foreach ($mElem as $sKey => $sValue) {
				if ($iMaxLevel%2) {
					$rgb = ($color++%2) ? "#888888" : "#BBBBBB";
				
				} else {
					$rgb = ($color++%2) ? "#8888BB" : "#BBBBFF";
				
				}
				
				$sOutput .= '<tr><td valign="top" style="width:40px;background-color:'.$rgb.';">';
				$sOutput .= '<strong>'.$sKey."</strong></td><td>";
				$sOutput .= print_nice($sValue,$iMaxLevel,$aPrintNiceStack);
				$sOutput .= "</td></tr>";
			}
			
			$sOutput .= "</table>";
			return $sOutput;
		}
		
		if ($mElem === null) {
			$sOutput .= "<font color=green>NULL</font>";
		
		} else if ($mElem === 0) {
			$sOutput .= "0";
		
		} else if ($mElem === true) {
			$sOutput .= "<font color=green>TRUE</font>";
		
		} else if ($mElem === false) {
			$sOutput .= "<font color=green>FALSE</font>";
		
		} else if ($mElem === "") {
			$sOutput .= "<font color=green>EMPTY STRING</font>";
		
		} else {
			$sOutput .= str_replace("\n","<strong><font color=red>*</font></strong><br>\n",$mElem);
		
		}
	
		return $sOutput;
	}


	/**
	 * 
	 * fnBacklinkBuilder
	 * $sHow può assumere i valori 'get' oppure 'input'.
	 *
	 */
	function fnBacklinkBuilder ($sBacklink, $sName, $sTable='', $sHow='get') {
		
		global $sAPP;
		
		$sValue = (string)(	!is_null(fnReadSessionValue($sName, 'main-table', $sAPP, $sTable)) ?
							fnReadSessionValue($sName, 'main-table', $sAPP, $sTable) :
							'');
		
		if ($sValue != '') {
			if ($sHow == 'get') {
				$sBacklink .= ($sBacklink == 'index.php' ? '?' : '&').$sName."=".$sValue;
			} else if ($sHow == 'input') {
				$sBacklink .= "<input type='hidden' name='".$sName."' value='".$sValue."'>";		
			}		
		}
		
		return $sBacklink;
	}


	/**
	 * 
	 * fnHtmlBacklinkFull
	 * $sHow può assumere i valori 'get' oppure 'input'.
	 * Generalmente se ($sHow == 'get') allora $sBacklink = 'index.php'; mentre se ($sHow == 'input')
	 * allora $sBacklink = ''.
	 *
	 */
	function fnHtmlBacklinkFull ($sHow='get', $sBacklink='index.php', $bSearchFormShow=false, $bTagsShow=false) {
		
		global $sAPP;
		
		$sTable = (!is_null(fnReadSessionValue('sTable', 'main-table', $sAPP)) ? fnReadSessionValue('sTable', 'main-table', $sAPP) : '');
		
		$sBacklink = fnBacklinkBuilder($sBacklink, 'sTable', '', $sHow);

		if ($bSearchFormShow)
			$sBacklink = fnBacklinkBuilder($sBacklink, 'sSearchTerms', '', $sHow);
		
		if ($bTagsShow)
			$sBacklink = fnBacklinkBuilder($sBacklink, 'sTag', '', $sHow);
		
		$aSelect = fnSettingsArray($sTable, 'select');
		if (sizeof($aSelect) > 0) {
			foreach ($aSelect as $sFilter) {
				$sBacklink = fnBacklinkBuilder($sBacklink, $sFilter['sField'], '', $sHow);
			}
		}
		
		$aRadiob = fnSettingsArray($sTable, 'radiob');
		if (sizeof($aRadiob) > 0) {
			$sBacklink = fnBacklinkBuilder($sBacklink, 'sShow', $sTable, $sHow);
		}
		
		$sBacklink = fnBacklinkBuilder($sBacklink, 'iSortingCols', $sTable, $sHow);
		if (!is_null(fnReadSessionValue('iSortingCols', 'main-table', $sAPP, $sTable)) && fnReadSessionValue('iSortingCols', 'main-table', $sAPP, $sTable) > 0) {
			for ($i=0; $i < fnReadSessionValue('iSortingCols', 'main-table', $sAPP, $sTable); $i++) {
				$sBacklink = fnBacklinkBuilder($sBacklink, 'iSortCol_'.$i, $sTable, $sHow);
				$sBacklink = fnBacklinkBuilder($sBacklink, 'sSortDir_'.$i, $sTable, $sHow);			
			}
		}
		
		$sBacklink = fnBacklinkBuilder($sBacklink, 'iDisplayStart', $sTable, $sHow);
		$sBacklink = fnBacklinkBuilder($sBacklink, 'iDisplayLength', $sTable, $sHow);
		
		return $sBacklink;
	}


	/**
	 *
	 * fnFieldsDataTypeArray
	 *
	 */ 
	function fnFieldsDataTypeArray ($sSelectFrom) {
		
		global $aWITH_CURRENCY_VALUE;
		global $aFieldsDataType;
		$aFieldsDataType = array();
		 
		$sQuery = "DESCRIBE `$sSelectFrom`";

		$rResult = custom_mysql_query($sQuery,'fnFieldsDataTypeArray()');
		
		if (mysql_num_rows($rResult) > 0) {
			while ($aRow = mysql_fetch_assoc($rResult)) {
				if (strcasecmp($aRow['Type'], 'tinyint(1) unsigned') == 0) {
					$aFieldsDataType ['checkbox'] [] = $aRow['Field'] ;
				
				} else if (strcasecmp($aRow['Type'], 'date') == 0) {
					$aFieldsDataType ['date'] [] = $aRow['Field'] ;
				
				} else if (strcasecmp($aRow['Type'], 'text') == 0) {
					$aFieldsDataType ['text'] [] = $aRow['Field'] ;
				
				} else if (strcasecmp($aRow['Type'], 'timestamp') == 0) {
					$aFieldsDataType ['timestamp'] [] = $aRow['Field'] ;
				
				} else if (strcasecmp($aRow['Type'], 'double') == 0) {
					$aFieldsDataType ['numeric'] [] = $aRow['Field'] ;
				
				} else if (strncasecmp($aRow['Type'], 'int', 3) == 0) {
					$aFieldsDataType ['numeric'] [] = $aRow['Field'] ;
				
				}
				
			}
		}
		
		if (isset($aWITH_CURRENCY_VALUE) && count($aWITH_CURRENCY_VALUE) > 0) {
			foreach ($aWITH_CURRENCY_VALUE as $sField) {
				$aFieldsDataType ['currency'] [] = $sField ;
			}
		}
		
	}	


	/**
	 *
	 * fnCheckFieldsDataType
	 *
	 */
	function fnCheckFieldsDataType ($sField, $sWhat) {
		
		global $aFieldsDataType;
		
		if (isset($aFieldsDataType[$sWhat])) {
			if (in_array($sField, $aFieldsDataType[$sWhat]))
				return true;
			else
				return false;
		} else { 
			return false;
		
		}
	}

		
	/**
	 *
	 * fnMailTemplate
	 *
	 */
	function fnMailTemplate ($sTemplate) {
		
		$sQuery = "SELECT * FROM `templates` WHERE `sTemplate`='$sTemplate'";
		$rResult = custom_mysql_query($sQuery, 'fnMailTemplate');
		
		if (mysql_num_rows($rResult) == 1) {
			$aTemplate = mysql_fetch_assoc($rResult);
		} else {
			$aTemplate = NULL;
		}
		
		return $aTemplate;
	}
	
	/**
	 *
	 * fnMailRecipients
	 *
	 */	
	function fnMailRecipients ($sRecipient, $aReferenceField=array('SIC'=>'iReferente')) {
		
		$sString = '';

		if (!empty($sRecipient)) {
			
			$aRecipients = explode("|", $sRecipient);
		
			foreach ($aRecipients as $sAddress) {
			
				if ($sAddress == 'MANAGER-SIC') {
					$sString .= (!empty($sString) ? ', ' : '')."Maddalena Branchi <mbranchi@ospedaliriuniti.bergamo.it>, Michele Andreoletti <mandreoletti@ospedaliriuniti.bergamo.it>"; 
				
				} else if ($sAddress == 'APPROVVIGIONAMENTI') {
					$sString .= (!empty($sString) ? ', ' : '')."Giovanni Acquaroli <gacquaro@ospedaliriuniti.bergamo.it>"; 	

				} else if ($sAddress == 'GLOBAL') {
					$sString .= (!empty($sString) ? ', ' : '')."Global Service <globalservice@ospedaliriuniti.bergamo.it>"; 	
				
				} else if ($sAddress == 'MANAGER-GLOBAL') {
					$sString .= (!empty($sString) ? ', ' : '')."Enrico Bruletti <Enrico.Bruletti@hospital-consulting.it>, Francesco Pezzatini <Francesco.Pezzatini@hospital-consulting.it>"; 
				
				} else if ($sAddress == 'UNITA') {
					
					global $aData;
					
					if (isset($aData['sUnitaEmail']) && !empty($aData['sUnitaEmail']) && is_valid_email($aData['sUnitaEmail']))
						$sString .= (!empty($sString) ? ', ' : '').$aData['sUnita']." <".$aData['sUnitaEmail'].">";
				
				} else if ($sAddress == 'DEC') {
					
					global $aData;
					
					if (isset($aData['sDecEmail']) && !empty($aData['sDecEmail']) && is_valid_email($aData['sDecEmail']))
						$sString .= (!empty($sString) ? ', ' : '').(isset($aData['sDEC']) && !empty($aData['sDEC']) ? $aData['sDEC'] : 'DEC')." <".$aData['sDecEmail'].">";
						
				} else if ($sAddress == 'RUP') {
					
					global $aData;
					
					if (isset($aData['sRupEmail']) && !empty($aData['sRupEmail']) && is_valid_email($aData['sRupEmail']))
						$sString .= (!empty($sString) ? ', ' : '').(isset($aData['sRUP']) && !empty($aData['sRUP']) ? $aData['sRUP'] : 'RUP')." <".$aData['sRupEmail'].">";
						
				} else {
					
					global $aRESOURCES;
					
					if (isset($aRESOURCES[$sAddress])) {
						
						$sQuery = fnGetResourcesQuery($sAddress, array('sEmail'), 1);
						$rResult = custom_mysql_query($sQuery);
						
						if (mysql_num_rows($rResult) > 0) {
	
							while ($aRow = mysql_fetch_assoc($rResult)) {
							
								global $aData;
								
								if (!empty($aReferenceField) && isset($aReferenceField[$sAddress]) && !empty($aReferenceField[$sAddress]) && isset($aData[$aReferenceField[$sAddress]]) && !empty($aData[$aReferenceField[$sAddress]])) {
									if ($aData[$aReferenceField[$sAddress]] == $aRow['id']) {
										if (is_valid_email($aRow['sEmail'])) {
											$sString .= (!empty($sString) ? ', ' : '').$aRow['sDescription']." <".$aRow['sEmail'].">";
										}
									}
								
								} else {
									if (is_valid_email($aRow['sEmail'])) {
										$sString .= (!empty($sString) ? ', ' : '').$aRow['sDescription']." <".$aRow['sEmail'].">";	
									}
								
								}
							
							}	
						
						}
					
					}
				
				}
				
			}
			
		}
		
		return $sString;
	
	}

	



	/**
	 * 
	 * Determina se una azione è autorizzata ($iAccessLvl).
	 * E' possibile utilizzare la funzione senza specificare $iAccessLvl solo per gli utenti con per cui 'iSysop'=1.
	 * @param 	string 		$sAction		azione: 'view', 'edit', 'delete', 'sysop'
	 * @param 	int 		$iAccessLvl
	 * @return 	boolean						true, false (azione autorizzata, azione non autorizzata)
	 */
	function is_allowed ($sAction, $iAccessLvl=0) {
		global $sAPP, $sSUITE_NAME;
		
		switch ($sAction) {
			case 'view':
				$iLvl = 1;
				break;
			case 'edit':
				$iLvl = 2;
				break;
			case 'delete':
				$iLvl = 3;
				break;
			case 'sysop':
				if (!is_null(fnReadSessionValue('iSysop')) && fnReadSessionValue('iSysop') == 1)
					return true;
				else
					$iLvl = 9;
				break;
			default:
				return false;
				break;
		}
		if ($iAccessLvl < $iLvl)
			return false;
		else
			return true;
	}
	

	



	/**
	 *
	 * fnQueryCheckViewTableSecurityCheck
	 *
	 */
	function fnQueryCheckViewTableSecurityCheck ($iView, $sTable) {
		
		global $aTABLE;
		
		$sTableSelectFrom = $aTABLE[$sTable]['sTableSelectFrom'];
		$sTableSelectWhere = $aTABLE[$sTable]['sTableSelectWhere'];
		$sTableSelectGroupBy = $aTABLE[$sTable]['sTableSelectGroupBy'];
		
		$sQuery = " SELECT * FROM `$sTableSelectFrom`
					WHERE $sTableSelectWhere AND `id` = $iView ";
		
		if ($sTableSelectGroupBy != '') {
			$sQuery .= " GROUP BY `$sTableSelectGroupBy` ";
		}
		
		return $sQuery;
	
	}

	function fnIsValidRadiob ($sTable, $sShow)  {
		$bIsValid = false;
		if (!empty($sShow))  {
			$aRadiob = fnSettingsArray($sTable, 'radiob');
			foreach ($aRadiob as $aButton)  {
				if ($aButton['sAlias'] == $sShow)
					$bIsValid = true;
			}
		}
		return $bIsValid;
	}	

	function fnCheckUsername ($sUsername, $sType) {
		$sQuery = fnQueryCheckUsername($sUsername, $sType);
		$rResult = custom_mysql_query($sQuery, 'fnCheckUsername()');
		if (mysql_num_rows($rResult)!=1) {
			return array();
		} else {
			$aRow = mysql_fetch_assoc($rResult);
			return $aRow;
		} 
	}
	
	function fnGetLastLogin ($sUsername) {
		$sLastLogin = '';
		$sQuery = fnQueryGetLastLogin($sUsername);
		$rResult = custom_mysql_query($sQuery, 'fnGetLastLogin()');
		if (mysql_num_rows($rResult) == 1) {
			$aRow = mysql_fetch_assoc($rResult);
			$sLastLogin = fnHtmlTimestamp($aRow['tsWhen']);
		} else {
			$sLastLogin = "<em>Nessun accesso effettuato</em>";	
		} 
		return $sLastLogin;
	}

	function fnColumnToField($i, $aSettings) {
		
		$aFieldArray = array();
		
		foreach ($aSettings as $aColumn)  {
			if (($aColumn['iTableShow'] == 1 || $aColumn['iExcelShow'] == 1) || $aColumn['sField'] == 'id')  {
				$sField = ($aColumn['sAlias']=='' ? $aColumn['sField'] : $aColumn['sAlias']);
				$aFieldArray[] = $sField;
			}
		}
		
		return $aFieldArray[$i];
	}

	function fnHtmlCreatedWhen ($sCreatedWhen, $bFullText= true, $sLabel="Scheda creata") {
		$html = fnHtmlTimestamp($sCreatedWhen, $bFullText, $sLabel, true);
		return $html;	
	}
	
	function fnHtmlLastModify ($sLastModify, $bFullText= true, $sLabel="Ultima modifica") {
		$html = fnHtmlTimestamp($sLastModify, $bFullText, $sLabel, true);
		return $html;	
	}
	
	function fnHtmlTrashWhen ($sTrashWhen, $bFullText= true) {
		$html = fnHtmlTimestamp($sTrashWhen, $bFullText, "Scheda cancellata", false);
		return $html;	
	}
		
	function fnHtmlTimestamp ($sTimestamp, $bFullText= false, $sLabel='', $bGrayText=false) {
		if ($sTimestamp != '0000-00-00 00:00:00') {
			list ($Y, $M, $D, $h, $m, $s) = preg_split('/[- \/.:]/', $sTimestamp);
			$sText = ($bFullText ? " $sLabel: " : "");
			$sClass = ($bGrayText ? "gray-text" : "");
			$html = "<span class='$sClass'>$sText<span class='prettydate' title='$Y-$M-$D"."T"."$h:$m:$s"."Z'>";
			$html .= "<span>$D/$M/".substr($Y,2)." $h:$m</span></span></span>";	
		} else {
			$html = '&nbsp;';
		}	 
		return $html;	
	}

	function fnRedirectToDashboard ($sMsg='') {
		header("Location:../index.php".(!empty($sMsg) ? "?sMsg=".$sMsg : ""));
		die();
	}
	
	function fnRedirectToLogin () {
		
		global $sSUITE_URL;
		
		// L'utente non è autenticato: eseguo un redirect alla pagina login.php
		$sRedirect = $_SERVER['PHP_SELF'];
		foreach ($_GET as $sKey => $sValue) {
			$sRedirect .= "&".$sKey."=".$sValue;
			}
	  	header ("Refresh: 2; URL=$sSUITE_URL/login.php?sRedirect=$sRedirect");
	  	echo "<div style=\"text-align:left; font:normal 12px Verdana, Arial, Helvetica, Sans-serif;\">";
	  	echo "<p>Reindirizzamento verso la pagina di autenticazione...<br>";
	  	echo "(Se non viene visualizzata la pagina di autenticazione, cliccare <a href=\"$sSUITE_URL/login.php?sRedirect=".$sRedirect."\">qui</a>)</p></div>";
	  	die();
	}

	function impress ($sFormat=':post_wordcount') {
		return preg_replace_callback('/:([a-zA-Z_]+)/',
	           'impress_callback', $sFormat);
	}

	function impress_callback($aMatches, $sArray='aData') {
		
		global $aData;
	
		if (is_array($aData) && isset($aData[$aMatches[1]]) && !empty($aData[$aMatches[1]])) {
			if (fnCheckFieldsDataType($aMatches[1], 'date')) {
				/* il campo in sql inizia con data_ oppure finisce con _date */
				if ($aData[$aMatches[1]]!='0000-00-00') {
					return date_convert($aData[$aMatches[1]],'html');
				} else {
					return $aMatches[0];
				}
			}
			return utf8_decode($aData[$aMatches[1]]);
		}
		
		return $aMatches[0];
	}

	function whichApp () {
		$sDirname = dirname($_SERVER['PHP_SELF']);
		$aPath = explode("/",$sDirname);
		return $aPath[sizeof($aPath)-1];
	}

	function date_convert($sDate, $sWhat) {
		
		if(strlen($sDate) <= 10 && strlen($sDate) >= 6 ) { /* verifica banale sulla lunghezza del campo inserito
													      * obbliga ad inserire la data in un formato aaaa-mm-gg
														  * oppure gg/mm/aaaa (oppure aa-m-g o g/m/aa)
														  */
			
			if ($sWhat == 'sql') { // converte nel formato memorizzato in SQL (usare prima di una istruzione INSERT)
				$aDate = preg_split('/[- \/.]/', $sDate);
				if (sizeof($aDate)==3) {  
					list($sDay, $sMonth, $sYear) = $aDate;
					if (!empty($sYear) && is_numeric($sYear) && !empty($sMonth) && is_numeric($sMonth) && !empty($sDay) && is_numeric($sDay)) {
						if (checkdate($sMonth,$sDay,$sYear)) { 
							$sDate = "$sYear-".(strlen($sMonth)==1 && $month <10 ? "0".$sMonth : $sMonth)."-".(strlen($sDay)==1 && $sDay <10 ? "0".$sDay : $sDay);
							return $sDate;	 
						} else {
							return "0000-00-00"; 
						}
					} else { 
						return "0000-00-00";	
					}		
				} else {
					return "0000-00-00";
				}
			
			} else if ($sWhat == 'html') { // converte nel formato per la pagina HTML (usare dopo di una istruzione SELECT)
				if ($sDate == "0000-00-00") {
					return "&nbsp;";
				} else {
					list($sYear, $sMonth, $sDay) = preg_split('/[- \/.]/', $sDate);
					if (!empty($sYear) && is_numeric($sYear) && !empty($sMonth) && is_numeric($sMonth) && !empty($sDay) && is_numeric($sDay)) {
						$sDate = "$sDay/$sMonth/$sYear";
						return $sDate;
					} else { 
						return "&nbsp;";
					}
				}	
			} else  { 
				return null;	
			}
		} else { 
			return null;
		}
	}

	function impress2view_id( $format='ID:view_id' ) {
		return preg_replace_callback('/ID:([0-9]+)/',
	           'impress2view_id_callback', $format);
	}

	function impress2view_id_callback ($matches) {
		global $sTABLE_SELECT_FROM;
		global $sTABLE_SELECT_GROUPBY;
		
		$viewItemLink = fnGetCurrentScriptName();
		$sQuery = "SELECT * FROM $sTABLE_SELECT_FROM WHERE id = '".$matches[1]."' ".($sTABLE_SELECT_GROUPBY ? " GROUP BY $sTABLE_SELECT_GROUPBY " : "");  			
		$rResult = custom_mysql_query($sQuery);
	  	if (mysql_num_rows($rResult) == 1) { // FIXME
	  		$aRow = mysql_fetch_assoc($rResult);
			return "<a href='$viewItemLink?id=".$matches[1]."'>(".$aRow['quantita'].")&nbsp;".$aRow['apparecchiatura']."</a>";
	  	}
		return $matches[0];
	}	

	function is_valid_email($string) {
		// FIXME
		if(eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $string)) { 
			return true;
		} else { 
			return false; 
		}
	}

	function is_valid_url($string) {
		// FIXME
		if(eregi('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $string)) { 
			return true;
		} else { 
			return false; 
		}
	}	
	
	function datediff($interval, $date1, $date2) { 
	    $seconds = $date2 - $date1; 
	    switch ($interval) { 
	        case "y":    // years 
	            list($year1, $month1, $day1) = preg_split('/[- \/.]/', date('Y-m-d', $date1)); 
	            list($year2, $month2, $day2) = preg_split('/[- \/.]/', date('Y-m-d', $date2)); 
	            $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1)); 
	            $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2)); 
	            $diff = $year2 - $year1; 
	            if($month1 > $month2) { 
	                $diff -= 1; 
	            } elseif($month1 == $month2) { 
	                if($day1 > $day2) { 
	                    $diff -= 1; 
	                } elseif($day1 == $day2) { 
	                    if($time1 > $time2) { 
	                        $diff -= 1; 
	                    } 
	                } 
	            } 
	            break; 
	        case "m":    // months 
	            list($year1, $month1, $day1) = preg_split('/[- \/.]/', date('Y-m-d', $date1)); 
	            list($year2, $month2, $day2) = preg_split('/[- \/.]/', date('Y-m-d', $date2)); 
	            $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1)); 
	            $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2)); 
	            $diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1); 
	            if($day1 > $day2) { 
	                $diff -= 1; 
	            } elseif($day1 == $day2) { 
	                if($time1 > $time2) { 
	                    $diff -= 1; 
	                } 
	            } 
	            break; 
	       case "w":    // weeks 
	            // Only simple seconds calculation needed from here on 
	            $diff = floor($seconds / 604800); 
	            break; 
	       case "d":    // days 
	            $diff = floor($seconds / 86400); 
	            break; 
	       case "h":    // hours 
	            $diff = floor($seconds / 3600); 
	            break; 
	       case "i":    // minutes 
	            $diff = floor($seconds / 60); 
	            break; 
	       case "s":    // seconds 
	            $diff = $seconds; 
	            break; 
	    } 
	    return $diff; 
	}

	function get_access_lvl($name) {
		$sql = "SELECT username, el, access_lvl FROM users_access_lvl WHERE username='".$_SESSION['username']."' and APP='$APP' AND el!='' AND tab='' AND field=''";
		$result = custom_mysql_query($sql);
		if (mysql_num_rows($result) > 0) {
			while ($row = mysql_fetch_assoc($result)) {
				if ($row['access_lvl']==0) {
					if (isset($menu[$row['el']])) unset($menu[$row['el']]);
				}
			}
		}
	}

	function timestamp_html($name, $label, $data, $reset=1) {
		global $action, $iAccessLvl, $tab, $iDEBUG_MSG;
		$iFieldAccessLvl = fnFieldAccessLvl($iAccessLvl, $tab, 'reset_'.$name);
		
		$html = '';
		
		if (!is_array($data) || !isset($data[$name]) || empty($data[$name]) || $data[$name] == '0000-00-00 00:00:00') {
			$value = "";
		} else  {
			list ($Y, $M, $D, $h, $m, $s) = preg_split('/[- \/.:]/', $data[$name]);
			$Y=substr($Y,2); // solo due cifre per l'anno
			$value = "$D/$M/$Y $h:$m";
		}
		
		$html = '';
		if ($value!='') {
			$html .= "<div class='inputLabel' "./*($action=='edit' ? "style='font-weight: bold;'" : "").*/">".$label."</div>";
			$html .= "<div class='inputField'>$value";
			if ($action=='edit' && is_allowed('edit',$iFieldAccessLvl) && $reset) {
				$html .= "&nbsp;<font style='font-weight: normal; color: #585858;'>reset</font>".
					"<input type='checkbox' name='reset_".$name."' value='1' ".
				"onClick=\"if(this.checked==true){alert('Selezionando questa opzione verrà nuovamente inviato un promemoria relativo alla scadenza dell\'autorizzazione');return;}\"></div>";
			}
			$html .= "</div>";
		}
		return $html;	
	}

	function float($str, $single_dot_as_decimal=TRUE) {
	 	if (preg_match("/([0-9\.,-]+)/", $str, $match)) {
			// Found number in $str, so set $str that number
			$str = $match[0];
			
			if(strstr($str, ',')) {
			// A comma exists, that makes it easy, because we assume it separates the decimal part.
				$str = str_replace('.', '', $str); // Erase thousand seps
				$str = str_replace(',', '.', $str); // Convert , to . for floatval command
				return floatval($str);	
			} else {
				// No comma exists, so we have to decide, how a single dot shall be treated
				if(preg_match("/^[0-9]*[\.]{1}[0-9-]+$/", $str) == TRUE && $single_dot_as_decimal == TRUE) {
					// Treat single dot as decimal separator
		 			return floatval($str);
				} else {
					// Else, treat all dots as thousand seps
					$str = str_replace('.', '', $str); // Erase thousand seps
					return floatval($str);
				}
			}
		} else {
			// No number found, return zero
			return 0;
		}
	}

	function hiddenInput($name, $data, $more='') {
		global $action;
		if (!is_array($data) || !isset($data[$name]) || empty($data[$name]))  {
			$value = ($action != 'edit' ? "&nbsp;" : "");
		} else {
			$value = $data[$name];
		}
		$html = ($action == 'edit' ? "<input type='hidden' name='$name' value=\"$value\" $more>" : "");
		return $html;	
	}

	function redirect_on_error ($url='index.php') {
	  		header ("Refresh: 2; URL=$url");
	  		echo "<div style=\"text-align:left; font:normal 12px Verdana, Arial, Helvetica, Sans-serif;\">";
	  		echo "<p>Si è verificato un errore. Reindirizzamento verso la pagina principale...<br>";
	  		echo "(Se non viene visualizzata la pagina principale, cliccare <a href='$url'>qui</a>)</p></div>";
			die();
	}
	
	function redirect_on_lowrights ($access_lvl=3, $url='index.php') {
		global $PREFIX; 
		if (!isset($_SESSION[$PREFIX.'access_lvl']) || $_SESSION[$PREFIX.'access_lvl'] < $access_lvl) {  
	  		header ("Refresh: 2; URL=$url");
	  		echo "<div style=\"text-align:left; font:normal 12px Verdana, Arial, Helvetica, Sans-serif;\">";
	  		echo "<p>Non si è autorizzati a visualizzare questa pagina. Reindirizzamento verso la pagina principale...<br>";
	  		echo "(Se non viene visualizzata la pagina principale, cliccare <a href='$url'>qui</a>)</p></div>";
			die();
		}
	}

	function fnQueryGetSettings ($sApp, $sTable, $sWhat='all') {
	
		switch ($sWhat) {
			case 'table':
				$sWhere = ' `iTableShow` = 1 ';
				break;
			case 'select':
				$sWhere = ' `iSelectShow` = 1 ';
				break;		
			case 'radiob':
				$sWhere = ' `iRadiobShow` = 1 ';
				break;	
			case 'excel':
				$sWhere = ' `iExcelShow` = 1 ';
				break;	
			default:
				$sWhere = ' 1 ';
				break;
		}
		
		$sQuery = "	SELECT * FROM `settings` WHERE $sWhere AND `sApp` = '$sApp' AND `sTable` = '$sTable' ORDER BY `iOrdering` ASC";
		return $sQuery;
		
	}	

	function fnGetParentDescription($iParent, $aParentsData) {
		
		if (isset($aParentsData[$iParent])) {
			return $aParentsData[$iParent];
		} else { 
			return null;
		}
		
	}

	/**
	 * 
	 * Visualizza un testo con un link al contenuto delle variabile $sQuery e $sRedirect (la funzione viene utilizzata quando $iDEBUG_MSG == 1)
	 * @param string $sQuery		query
	 * @param string $sRedirect		indirizzo utilizzato per l'istruzione header("Location: $sRedirect")
	 */
	function fnHtmlTransactFooter($sQuery='', $sRedirect='') {
		if (fnShowDebugMsg()) {
			echo "<br/><textarea style='margin: 10px 0px;'>$sQuery</textarea>";
			echo "<br/><b>&raquo;&nbsp;<a href='".(!empty($sRedirect) ? $sRedirect : "index.php")."'>redirect</a></b>";
			echo "<br/><b>&raquo;&nbsp;</b><font style='font-size:.8em'>".(!empty($sRedirect) ? $sRedirect : "index.php")."</font>";
		} else {
			header("Location: ".(!empty($sRedirect) ? $sRedirect : "index.php"));
			die();
		}
	}

	function fnQueryTagRemoveAll ($iView, $sTABLE_SELECT_FROM) {
		global $sSUITE_NAME, $sAPP;
		
		$sQuery = "DELETE FROM `tags` WHERE `sApp`='$sAPP' AND `sTable`='$sTABLE_SELECT_FROM' AND `iView`='$iView'";	
		return $sQuery;		
	}
						
	function fnQueryCheckUsername ($sUsername, $sType) {
		$sQuery = "SELECT * FROM `users` WHERE `sUsername`='$sUsername' AND `sType`='$sType'";	
		return $sQuery;
	}

	function fnQueryGetLastLogin ($sUsername) {
		$sQuery = "SELECT * FROM `log` WHERE `id` = (SELECT MAX(`id`) FROM `log` WHERE `sUsername` = '$sUsername' AND `sDescription` = 'LOGIN' GROUP BY `sUsername`)";
		return $sQuery;	
	}

	function fnQueryGetAllGroups () {
		$sQuery = "SELECT `sUsername` AS `sGroup`, `sDisplayname`
				FROM `users`
				WHERE `sType`='group' ORDER BY `sGroup`";	
		return $sQuery;
	}
	
	function fnQueryGetMembersUsers ($sGroup) {
		$sQuery = "SELECT `users_groups_lnk`.`sUser`, `users`.`sDisplayname`
				FROM `users_groups_lnk`
				LEFT OUTER JOIN `users` ON `users`.`sUsername` = `users_groups_lnk`.`sUser`
			 	WHERE `users_groups_lnk`.`sGroup` = '$sGroup'
			 	ORDER BY `users_groups_lnk`.`sUser`";	
		return $sQuery;
	}
	
	function fnQueryGetAllUsers () {
		$sQuery = "SELECT `sUsername` AS `sUser`, `sDisplayname` FROM `users`
				WHERE `sType`='user' ORDER BY `sUsername`";	
		return $sQuery;
	}			
		
	/**
	 *
	 * fnQueryGetAppsAccessLvl
	 *
	 */
	function fnQueryGetAppsAccessLvl ($sUsername, $sType, $sApp='') {
		
		$sQuery = "SELECT `sApp`, `iAccessLvl` FROM `users_access_lvl`
			WHERE `sUsername`='$sUsername' AND `sType`='$sType' AND `sWhat`='app' ";
		
		if ($sApp!='') {
			global $aSUITE;
			if (isset($aSUITE[$sApp])) {
				$sQuery .= " AND `sApp`='$sApp' ";
			}
		}
		
		return $sQuery;
		
	}			


	/**
	 *
	 * fnQueryGetAppAccessLvl
	 *
	 */
	 function fnQueryGetAppAccessLvl ($sUsername, $sType, $sApp) {
		$sQuery = fnQueryGetAppsAccessLvl($sUsername, $sType, $sApp);
		return $sQuery;
	}		
	
	function fnQueryUsers ($sWhat) {
		$sQuery = "SELECT * FROM `users` WHERE `sType`='$sWhat' ORDER BY `sUsername` ASC";
		return $sQuery;
	}	
	
	function fnQueryRegisterEntries ($iView) {
		$sQuery = "SELECT * FROM `contratti_verifiche` WHERE `contratto_id` = '$iView' ";
		return $sQuery;	
	}
		
	/**
	 *
	 * fnTablesNamesOptions()
	 * Funzione utilizzata in settings.php, const.php per popolare il campo di input <select id='sTable' name='sTable'>.
	 * Se non utilizzassi la funzione, rimarrebbero impostate tutte le variabili relative all'ultima
	 * $sTable presente in $aTABLE (ovvero: $sTableName, $sTableDescription, ..., $bShowSearchForm, ...)
	 * e questo potrebbe creare casini (ad esempio se rimane impostata $bShowSearchForm poi ci sono
	 * casini nella visualizzazione del campo di ricerca in template.php).
	 *
	 */
	 
	function fnTablesNamesOptions ($sWhat='visibile')  {
		
		// $sWhat può assumere i seguenti valori: 'all', 'visibile', 'hidden'
		
		$html = '';
		global $aTABLE;
		
		foreach ($aTABLE as $sTable => $aValues) { 
				//	$sWhat='visibile' => $aValues['iShow'] = 1
				//	$sWhat='hidden' => $aValues['iShow'] = 0
				//	$sWhat='all' => $aValues['iShow'] = $aValues['iShow'] (ossia: visualizzo tutto!)
				if ($aValues['iShow'] == ($sWhat=='visibile' ? 1 : ($sWhat=='hidden' ? 0 : $aValues['iShow']))) { 
					if ($aValues['sTableName'] != 'spacer') { 
						$html .= "	<option value='$sTable'>".$aValues['sTableName']."</option>";
					} else {
						$html .= "	<option value=''>---</option>";
					}
				}
		}
		
		return $html;
	
	}

	/**
	 *
	 * in_aSelect()
	 * Questa funzione, utilizzata in table.php, mi serve per verificare quando un campo è presente
	 * nell'array $aSelect. Utilizzo questa funzione per sapere quando è necessario che due campi
	 * sia contemporaneamente presenti nell'array $aSelect (ad esempio: iDipartimento e iUnita) perchè
	 * sono previste azioni concatenate quando cambia la selezione di uno dei due campi.
	 *
	 */

	function in_aSelect ($sField) {

		global $aSelect;

		foreach ($aSelect as $aFilter) {
			if ($sField == $aFilter['sField'])
				return true;
		}

		return false;

	}
	
	/**
	 *
	 * fnGetAppAccessLvl()
	 *
	 */
	 
	function fnGetAppAccessLvl ($sApp) {
		return fnReadSessionValue($sApp, 'AccessLvl', $sApp, 'app');
	}

	
	/**
	 *
	 * fnDisplayAccessLvl()
	 *
	 */

	function fnDisplayAccessLvl ($iAccessLvl, $sHow) {		
		switch ($iAccessLvl) {
			case -1:
				$sText = 'accesso negato';
				$sHtml = "<span class='access-denied'>$sText</span>";
				break;	
			case 0:
				$sText = 'non definito';
				$sHtml = "<span class='access-empty'>$sText</span>";
				break;	
			case 1:
				$sText = 'visualizza';
				$sHtml = "<span class='access-allowed'>$sText</span>";
				break;			
			case 2:
				$sText = 'modifica, visualizza';
				$sHtml = "<span class='access-allowed'>$sText</span>";
				break;
			case 3:
				$sText = 'elimina, modifica, visualizza';
				$sHtml = "<span class='access-allowed'>$sText</span>";
				break;
			case 9:
				$sText = 'sysop, elimina, modifica, visualizza';
				$sHtml = "<span class='access-allowed'><span class='access-sysop'>sysop</span>, elimina, modifica, visualizza</span>";
				break;
		}
		if ($sHow == 'text') {
			return $sText;
		} else if ($sHow == 'html') {
			return $sHtml;
		}
	}	
	
	/**
	 *
	 * fnMessageFlash()
	 *
	 */	 
	 function fnMessageFlash ($sName='sMsg') {
	 
		$html ='';
		
		if (isset($_GET[$sName]) && !empty($_GET[$sName])) {
		
			$sMsg = trim($_GET[$sName]);
			
			switch ($sMsg) {
				
				case 'addsuccess':
					$sClass = "message";
					$sLabel	= '';
					$sText 	= "Scheda inserita con successo";
					break;
				
				case 'delsuccess':
					$sClass = "highlight";
					$sLabel	= '';
					$sText 	= "Scheda cancellata";
					break;
				
				case 'restored':
					$sClass = "message";
					$sLabel	= '';
					$sText 	= "Scheda recuperata dal cestino";
					break;
				
				case 'trashed':
					$sClass = "error";
					$sLabel	= "Errore";
					$sText 	= "Non è possibile modificare le schede spostate nel cestino";
					break;
				
				case 'lowrights':
					$sClass = "error";
					$sLabel	= "Errore";
					$sText 	= "Non si dispone di autorizzazioni sufficienti per eseguire l'operazione richiesta";
					break;
				
				case 'lowrights4new':
					$sClass = "highlight";
					$sLabel	= '';
					$sText 	= "Non si dispone di autorizzazioni sufficienti per creare una nuova scheda";
					break;
				
				case 'uploadsuccess':
					$sClass = "message";
					$sLabel	= '';
					$sText 	= "Allegato aggiunto con successo";
					break;
				
				case 'uploaderror':
					$sClass = "error";
					$sLabel	= "Errore";
					$sText 	= "Errore durante l'upload dell'allegato";
					break;
				
				case 'notfound':
					$sClass = "error";
					$sLabel	= "Errore";
					$sText 	= "Scheda non trovata: impossibile eseguire l'operazione richiesta";
					break;
				
				case 'updsuccess':
					$sClass	= "message";
					$sLabel	= '';
					$sText	= "Modifiche salvate con successo";					
					break;	
				
				case 'notauthorized':
					$sClass = "error";
					$sLabel = "Errore";
					$sText	= "Non si dispone di autorizzazioni sufficienti per accedere all'applicazione richiesta";
					break;
				
				case 'addextsuccess':
					$sClass = "message";
					$sLabel	= '';
					$sText 	= "Nuova scheda prova visione (rinnovo) creata con successo";
					break;
				
				default:
					$sClass = "highlight";
					$sLabel	= '';
					$sText	= urldecode($sMsg);
					break;	
			
			}
			
			$html .= "<div class='ui-corner-all ui-message-flash message-flash ui-state-$sClass'>
				<p>".(!empty($sLabel) ? "&nbsp;<strong>$sLabel:</strong>&nbsp;" : '')."$sText</p></div>";
	
		}
		
		return $html;
	
	}	
	
	/**
	 * 
	 * fnShowDebugMsg()
	 * Funzione utilizzata per stabile se visualizzare i messaggi di debug.
	 * 
	 * @param boolean $bSysop		se $bSysop == true il messaggio verrà visualzzato solo agli
	 *								amministratori/sysop
	 *
	 * @param integer $iAccessLvl	se $bSysop == true è opportuno (ma non obligatorio) inserire
	 *								$iAccesLvl per poter dare alla funzione is_allowed() tutte lea
	 *								informazioni necessarie. In caso non si inserisca $iAccessLvl
	 *								la funzione considererà come sysop solo gli amministratori di 
	 *								sistema, e non gli amministratori della singola applicazione.
	 *
	 * @return boolean
	 *
	 */
	 
	function fnShowDebugMsg	($bSysop=true, $iAccessLvl=0) {
		
		if (fnReadSessionValue('iDebugMsg') == 1) {
			if ($bSysop) {
				if (is_allowed('sysop', $iAccessLvl)) {
					return true;
					
				} else {
					return false;
					
				} 
			}

			return true;
			
		} else {
			return false;
			
		}
	
	}	

	/**
	 *
	 * fnTableBorder()
	 * La funzione serve per stabilire se è necessario o meno visualizzare una tabella con border='1'.
	 * Le tabelle vengono visualizzate con border='1' quando l'utente è un sysop di sistema e quando
	 * $_SESSION['DebugMsg'] == 1.
	 *
	 */
	 
	function fnTableBorder() {
		if (fnShowDebugMsg())
			return "1";
		else
			return "0";
	}

	/**
	 *
	 * fnIsScriptInRoot()
	 * Restituisce 'true' se lo script è nella document root (esempio: http://arcadia/index.php).
	 * Restituisce 'false' se lo script è nella directory di un'applicazione  (esempio: http://arcadia/budget/index.php).
	 *
	 * La funzione si basa sul confronto tra $sSUITE_URL e $_SERVER['SCRIPT_NAME'].
	 *
	 */	 
	function fnIsScriptInRoot () {
		
		$sScriptName = $_SERVER['SCRIPT_NAME'];
    	$aScriptName = explode('/', $sScriptName);
   
    	global $sSUITE_URL;
		$aBaseURL = explode('/', $sSUITE_URL);

		foreach ($aScriptName as $sKey => $sValue) {
			if (in_array($sValue, $aBaseURL)) {
				unset($aScriptName[$sKey]);
				
			}
      	}
      	
      	if (count($aScriptName) > 1)
      		return false;
      	else
      		return true;
    
    }

	/**
	 *
	 * fnCurrentScript ()
	 * Restituisce il nome dello script, senza il percorso completo.
	 *
	 * Ad esempio se $_SERVER['SCRIPT_NAME'] contiene '/~michele/arcadia_dev/budget/index.php'
	 * questa funzione restituisce il valore 'index.php'.
	 *
	 */	 
	function fnCurrentScript () {
		$sScriptName = $_SERVER['SCRIPT_NAME'];
    	$aScriptName = explode('/', $sScriptName);
   	 	
   	 	$sCurrentScript = $aScriptName[(count($aScriptName)-1)];
    	
    	return $sCurrentScript;
	}

	function fnShowTooltipField ($sField, $sLabel, $bEuro=false) {
		
		global $iAccessLvl;
		global $aFieldsDataType;
		global $aData;
		
		$sString = '';
		
		$iFieldAccessLvl = fnFieldAccessLvl($iAccessLvl, 0, $sField);
		
			if (is_allowed('view', $iFieldAccessLvl) && !empty($aData[$sField])) {
				
				if (fnCheckFieldsDataType($sField, 'checkbox')) {
					
					$sFilename = "images/".strtolower(substr($sField,1));
					
					if (!file_exists($sFilename."_on.png") || !file_exists($sFilename."_off.png")) {
						$sFilename = "../themes/common/images/wcheck";
					}
					
					if ($aData[$sField] == 'X' || $aData[$sField] == 1) {
						$sString = "<img src='$sFilename".($aData[$sField] == 'X' || $aData[$sField] == 1 ? '_on' : '_off').".png' border='0'>";
						$sString .= "&nbsp;<span class='".(($aData[$sField] == 'X' || $aData[$sField] == 1) ? 'label' : 'label-off')."'>$sLabel</span>";
					}
					
				} else if ($sField == 'sPriorita') { 
				
					$sPriorita = array('3'=>"Bassa priorità", '2'=>"Media priorità", '1'=>"Alta priorità", '9'=>"Fuori uso");
					$sString = ($aData[$sField] != '' ? "<img src='images/pr_".$aData[$sField].".png' border='0' />" : "");
					$sString .= (isset($sPriorita[$aData[$sField]]) ? "&nbsp;<span class='label'>$sLabel:</span>".$sPriorita[$aData[$sField]] : '');
				
				} else  { 
					
					if (fnCheckFieldsDataType($sField, 'date'))
						$sValue = date_convert($aData[$sField], 'html');

					else if ($bEuro) // qui dovrebbe andare 
						$sValue = number_format($aData[$sField],(intval($aData[$sField])==$aData[$sField] ? 0 : 2),',','.');
					
					else 
						$sValue = $aData[$sField];
		
					$sString = "<span class='label'>$sLabel:</span>&nbsp;".$sValue;
				
				}
					
				return $sString.'<br/>';
				
		}
	}

	/**
	 * 
	 * col2chr
	 * Here is a function that will convert column numbers in to a letters for use in a spreadsheet.
	 * It is limited up to 'ZZ' but can easliy by modifed.
	 * 
	 * @param	integer	$a
	 * @return	string
	 *
	 */	 
	 function col2chr ($a) { 
        if ($a < 27) { 
            return strtoupper(chr($a+96));    
        } else { 
            while ($a > 26) { 
                $b++; 
                $a = $a-26;                
            }                   
            $b = strtoupper(chr($b+96));    
            $a = strtoupper(chr($a+96));                
            return $b.$a; 
        }
    }


	/**
	 *
	 * fnGetAccessLvl
	 *
	 */	
	function fnGetAccessLvl ($sWhat='app', $mName='') {
		
		$iAccessLvl = null;
		
		global $sAPP;

		if (!is_null(fnReadSessionValue($mName, 'AccessLvl', $sAPP, $sWhat)))  {
			$iAccessLvl = fnReadSessionValue($mName, 'AccessLvl', $sAPP, $sWhat);
		}
		
		return $iAccessLvl;

	}		
	
	
	
	/**
	 * 
	 * fnViewAccessLvl
	 * Questa funzione calcola qual è il livello di accesso per uno specifico record ($iView).
	 *
	 * La funzione assegna a $iAccessLvl il valore minimo di iAccessLvl definito per le tabelle di
	 * cui la scheda fa parte (vengono considerate solo le tabelle inserite nell'array $aTABLE_SECURITY_CHECK).
	 *
	 */
	 function fnViewAccessLvl ($iView, $aMenu, $aTableSecurityCheck) {
		
		if (empty($iView) || !is_numeric($iView)) {
			// Errore: $iView non valido; viene negato l'accesso; interrompo l'esecuzione della funzione.
			return -1; 
		}
		
		global $sViewItemLink;
		
		//$iAccessLvl di default è quello 'globale' di $sViewItemLink (se definito) oppure quello dell'applicazione
		$iAccessLvl = fnFieldAccessLvl(fnGetAccessLvl(), $sViewItemLink);
		
		foreach ($aMenu as $sTable => $aValues) {

			
			//
			// verifico che la tabella che sto considerando sia collegata allo script che è in esecuzione ($sViewItemLink)
			//
			// 28/2/2011: ho inserito la condizione isset($aValues['sViewItemLink']) perchè in alcuni casi non è definito
			// (ad esempio quando per le tabelle 'spacer' $aTABLE['spacer-1'] = array('sTableName' => 'spacer', 'iShow' => 1);
			//
			
			if (isset($aValues['sViewItemLink']) && $sViewItemLink == $aValues['sViewItemLink']) { 
				
				// $aTableSecurityCheck contiente l'elenco delle tabelle ('sTable') per cui è richiesto
				// un controllo sui livelli di accesso
				
				if (in_array($sTable, $aTableSecurityCheck)) {
					
					if (!is_null(fnGetAccessLvl('table', $sTable)) && fnGetAccessLvl('table', $sTable) < $iAccessLvl) {
					
						// eseguo la prossima query solo se è specificato un 'iAccessLvl' per l'elenco
						// preso in considerazione e se questo 'iAccessLvl' è minore del valore già assegnato
						// a $iAccessLvl
					
						$sQuery = fnQueryCheckViewTableSecurityCheck($iView, $sTable);
						$rResult = custom_mysql_query($sQuery, 'fnQueryCheckViewTableSecurityCheck()');
		  				
		  				// se mysql_num_rows($rResult) è uguale a 1 vuol dire che il record $iView fa parte della tabella
		  				// che sto considerando
		  				
		  				if (mysql_num_rows($rResult) == 1) {
		  					$iAccessLvl = fnGetAccessLvl('table', $sTable); 					
		  				}

					}

				}
			
			}
		
		} 

		return $iAccessLvl;

	}	
	
	
	
	/**
	 *
	 * fnHtmlSearchForm
	 *
	 */
	function fnHtmlSearchForm ($sSearchFormLabel, $bShowTags, $sTable, $sSearchTerms='') {
		
		$html  = "<form id='search-form' action='index.php'>";
		$html .= "	<input type='hidden' name='sTable' value='$sTable' />";
		
		$html .= "	<input type='text' name='sSearchTerms' id='sSearchTerms'
						
						style='margin-top:12px; margin-left:12px; margin-right:6px; font-weight:bold;
								color: ".(isset($sSearchTerms) && !empty($sSearchTerms) ? "black" : "gray").";'
						
						onFocus=\"if (this.value == '".$sSearchFormLabel."')
								{this.value = ''; this.style.color='black'; }\"
						
						onBlur=\"if(this.value == '')
								{this.value = '".$sSearchFormLabel."'; this.style.color='gray'}\"
						
						size='12'
						
						value='".(isset($sSearchTerms) && !empty($sSearchTerms) ? $sSearchTerms : $sSearchFormLabel)."' />
						
					<img id='search-form-submit' src='../themes/common/images/search.png' title='$sSearchFormLabel' alt='$sSearchFormLabel'>";
						
		$html .=  	fnHtmlHiddenInputs(false, $bShowTags, $sTable);
		
		$html .= "</form>";
		
		$html .= "<div id='search-form-dialog' title='Ricerca...'>
					<p>Per eseguire una ricerca inserire, anche parzialmente, la parola che si desidera trovare.</p>
				  </div>";	
		
		global $sJsDocumentReady;
		
		$sJsDocumentReady .= "
				$('#search-form-dialog').dialog( {
					autoOpen: false,
					resizable: false,
					modal: true,
					buttons: {
						Ok: function() {
							$(this).dialog('close');
						}
					}
				});
			
				$('#search-form-submit').click(function() {
					if (sSearchTerms !='') {
						$('#search-form').submit();
					} else {
						$('#search-form-dialog').dialog('open');	
					}
					return false;
					
				}).mouseover(function() {
					$(this).attr('src', '../themes/common/images/search_f2.png')
 				
 				}).mouseout(function() {
					$(this).attr('src', '../themes/common/images/search.png')
 				
 				}); ";
	
		return $html;
	}	
	
	/**
	 *
	 * fnSearchFilter
	 *
	 */	 
	function fnSearchFilter ($sWhat, $sSearchTerms, $aSearchFields) {
		
		$sWhere = $sTableTitle = '';

		/**
		 * Vengono ignorate le parole lunghe meno di 2 caratteri.
		 */
			 
		if (!is_null(fnReadSessionValue('sUsername'))) {
			$iAccessLvl = fnGetAccessLvl();
			
			if ($sSearchTerms != '' && strlen($sSearchTerms) >= 2) {
				$sWhere = " AND (";
				foreach ($aSearchFields as $sField) {
					$iFieldAccessLvl = fnFieldAccessLvl($iAccessLvl, '', $sField);
					if (is_allowed('view', $iFieldAccessLvl)) {
						$sWhere .= " $sField LIKE '%$sSearchTerms%' OR ";
					}
				}
				$sWhere = substr($sWhere, 0, -3).") ";
			}
		
		} else {
			// Questa condizione viene utilizzata per OpenSearch XML
			if ($sSearchTerms != '' && strlen($sSearchTerms) > 2) {
				$sWhere = " AND (";
				foreach ($aSearchFields as $sField) {
					$sWhere .= " $sField LIKE '%$sSearchTerms%' OR ";
				}
				$sWhere = substr($sWhere, 0, -3).") ";
			}
		
		}
	
		$sTableTitle .= "<span class='table-title-more' id='table-title-search'> &raquo; Risultato ricerca: <em class='table-title-value'>$sSearchTerms</em></span>";
		
		switch ($sWhat) {
			case 'sTableTitle':
				return $sTableTitle;
				break;
			case 'sWhere':
				return $sWhere;
				break;		
			default:
				return array(	'sTableTitle' => $sTableTitle,
								'sWhere' => $sWhere				);
				break;
		}
	}

	/**
	 *
	 * fnQuerySettingsArray
	 *
	 */

	 function fnQuerySettingsArray ($sWhere) {
		$sQuery = "SELECT * FROM `settings` WHERE $sWhere ORDER BY `iOrdering` ASC";
		return $sQuery;
	}

	/**
	 *
	 * fnSettingsArray
	 *
	 */	 
	function fnSettingsArray ($sTable, $sWhat='') {
		
		global $sAPP;
		
		$aSettings = array();
		$sWhere = " `sApp` = '$sAPP' AND `sTable` = '$sTable' ";
		
		switch ($sWhat) {
			case 'table': $sWhere .= " AND (`iTableShow` = '1') ";
				break;		
			case 'radiob': $sWhere .= " AND (`iRadiobShow` = '1') ";
				break;
			case 'select': $sWhere .= " AND (`iSelectShow` = '1') ";
				break;		
			case 'excel': $sWhere .= " AND (`iExcelShow` = '1') ";
				break;
			default: $sWhere .= " AND '1' ";
				break;
		}
		
		$sQuery = fnQuerySettingsArray($sWhere);
		$aSettings = fnGetDataFromQuery($sQuery, 'fnQuerySettingsArray()');
		
		return $aSettings;
	}

	/**
	 * 
	 * fnArray2Check
	 * Questa funzione viene utilizzata per creare l'array $aCheck utilizzato all'interno della
	 * funzione fnGetTableVal().
	 *
	 * Praticamente questa funzione viene usata per convertire l'array $aTABLE e poter verificare che
	 * $_GET['sTable'] sia valido, ovvero che esista $aTABLE[$_GET['sTable']].
	 * 
	 */
	 
	function fnArray2Check($aData) {
		
		$aArray = array();
		
		foreach ($aData as $sKey => $mValue) {
			$aArray[] = $sKey;
		}
		
		return $aArray;
	}	

	/**
	 *
	 * fnGetValueFromGET
	 *
	 */
	function fnGetValueFromGET ($aAllowedVars=array()) {
		
		/**
		 * ATTENZIONE: $sGETName e $sGETValue sono due nomi di variabile che non devono
		 * mai essere usate come parametri di tipo $_GET, altrimenti si creano casini con la
		 * dichiarazione global ${$sGETName} (in altre parole: questa funzione non funzionerebbe!)
		 *
		 */
		 
		foreach ($_GET as $sGETName => $sGETValue) {
			
			if ((isset($aAllowedVars) && is_array($aAllowedVars) && !empty($aAllowedVars) &&
					in_array($sGETName, $aAllowedVars)) || empty($aAllowedVars)) {
			
				global ${$sGETName};
			
				$$sGETName = trim($sGETValue);	

				if(get_magic_quotes_gpc()) {
					if (!empty($$sGETName)) {
						$$sGETName = stripslashes($$sGETName);
					}
				}
			
				$$sGETName = mysql_real_escape_string($$sGETName);
				fnVarDebug($sGETName, $$sGETName);
			}
			
		}
	
	}

	/**
	 *
	 * fnGetValueFromPOST
	 *
	 */
	function fnGetValueFromPOST ($aAllowedVars=array()) {
	
		/**
		 * ATTENZIONE: $sPOSTName e $sPOSTValue sono due nomi di variabile che non devono
		 * mai essere usate come parametri di tipo $_POST, altrimenti si creano casini con la
		 * dichiarazione global ${$sPOSTName} (in altre parole: questa funzione non funzionerebbe!)
		 *
		 */
		 
		foreach ($_POST as $sPOSTName => $sPOSTValue) {
			
			if ((isset($aAllowedVars) && is_array($aAllowedVars) && !empty($aAllowedVars) &&
					in_array($sPOSTName, $aAllowedVars)) || empty($aAllowedVars)) {
			
				global ${$sPOSTName};
			
				$$sPOSTName = trim($sPOSTValue);	
			
				if(get_magic_quotes_gpc()) {
					if (!empty($$sPOSTName)) {
						$$sPOSTName = stripslashes($$sPOSTName);
					}
				}
			
				$$sPOSTName = mysql_real_escape_string($$sPOSTName);			
				fnVarDebug($sPOSTName, $$sPOSTName);
			}

		}

	}
	
	/**
	 *
	 * fnVarDebug
	 *
	 */			
	function fnVarDebug ($sKey, $sValue) {
		
		global $sAPP;

		if (   (fnShowDebugMsg() && !isset($_SESSION)) ||
			   (fnShowDebugMsg() && is_allowed('sysop', fnGetAppAccessLvl($sAPP)))	) {
			
				echo "<strong>$sKey</strong>: </em>$sValue</em></br>";
		
		}

	}


	/**
	 *
	 * fnGetVal
	 *
	 */			
	function fnGetVal ($sName, $sDefault='') {
		
		if (isset($_GET[$sName])) {
			$sValue = trim($_GET[$sName]);
			if(get_magic_quotes_gpc()) {
				if (!empty($sValue)) {
					$sValue = stripslashes($sValue);
				} 
			}
			$sValue = mysql_real_escape_string($sValue);
		
		} else {
			$sValue = $sDefault;
		
		}
		
		return $sValue;
	}

	/**
	 *
	 * fnGetInt
	 *
	 */
	function fnGetInt ($sName, $iDefault=0, $sMin='', $sMax='') {
	
		if (isset($_GET[$sName]) && is_numeric(trim($_GET[$sName]))) {
			$sValue = round(trim($_GET[$sName]));
			
			if ($sMin != '' && is_numeric($sMin) && ($sMin<$sMax)) {
				$sValue = max($sValue, round($min));
			}
			
			if ($sMax != '' && is_numeric($sMax) && ($sMin<$sMax)) {
				$sValue = min($sValue, round($max));
			}
		
		} else {
			$sValue = $iDefault;
		
		}
		
		return $sValue;
	}

	/**
	 *
	 * fnGetTableInt
	 *
	 */		
	function fnGetTableInt ($sName, $iDefault=0, $sTable='', $sMin='', $sMax='', $bUpdateSession=true) {
		
		global $sAPP;
		
		$iValue = fnGetInt($sName, $iDefault, $sMin, $sMax);
		
		if ($bUpdateSession) {
			fnSaveSessionValue($iValue, $sName, 'main-table', $sAPP, $sTable);
		}
		
		return $iValue;
	}

	/**
	 *
	 * fnGetTableVal
	 *
	 */		
	function fnGetTableVal ($sName, $sDefault='', $sTable='', $aCheck=array(), $bUpdateSession=true) {
	
		// esempio: fnGetTableVal('sTable', fnTableDefault($sTABLE_DEFAULT, $aTABLE), '', fnArray2Check($aTABLE));
		
		global $sAPP;
		
	 	$sValue = fnGetVal($sName, $sDefault);
	 	
	 	if (is_array($aCheck) && !empty($aCheck)) {
			if (in_array($sValue, $aCheck)) {
				$sValue = $sValue;
			} else {
				$sValue = $sDefault;
			}
		}
		
		if ($bUpdateSession) {
			fnSaveSessionValue($sValue, $sName, 'main-table', $sAPP, $sTable);
		}

		return $sValue;
	}		
	
	
	
	/**
	 *
	 * fnReadSessionValue
	 * Read $_SESSION ('', 'AccessLvl', 'main-table')
	 *
	 */	 
	function fnReadSessionValue ($mName, $sParam='', $sApp='', $sWhat='', $bBackup=false) {
		
		global $sSUITE_NAME;

		switch ($sParam) {
						
			case '' :
				if (is_string($mName) && isset($_SESSION[$sSUITE_NAME][$mName])) {
					return $_SESSION[$sSUITE_NAME][$mName];
				}
				break;

			case 'AccessLvl' :
				switch ($sWhat) {
					case 'app' :
						if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat])) {
							return $_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat];
						}
					case 'table' :
						if ((is_array($mName) && isset($mName['sTable'])) || is_string($mName)) {
							$sName = (is_array($mName) && isset($mName['sTable']) ? $mName['sTable'] : (is_string($mName) ? $mName : ''));
							if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName]))
								return $_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName];
						}
						break;
					case 'viewitemlink' :
						if ((is_array($mName) && isset($mName['sViewItemLink'])) || is_string($mName)) {
							$sName = (is_array($mName) && isset($mName['sViewItemLink']) ? $mName['sViewItemLink'] : (is_string($mName) ? $mName : ''));
							if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName]))
								return $_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName];
						}
						break;						
					case 'tab' :
						if (is_array($mName) && isset($mName['sViewItemLink']) && isset($mName['sTab'])) {
							if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']]))
								return $_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']];
						}
						break;	
					case 'field' :
						if (is_array($mName) && isset($mName['sViewItemLink']) && isset($mName['sTab']) && isset($mName['sField'])) {
							if ($bBackup) {
								if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl']['aBackup'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']]))
									return $_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl']['aBackup'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']];		
							} else { 
								if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']]))
									return $_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']];	
							}
						}
						break;	
				}
				break;	
			
			case 'main-table' :
				if ($sWhat != '') {
					if (is_string($mName) && isset($_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$sWhat][$mName])) {
						return $_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$sWhat][$mName];
					}
				} else {
					if (is_string($mName) && isset($_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$mName])) {
						return $_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$mName];
					}					
				} 	
				break;
				
		}
		
		return NULL;
		
	}


	
	/**
	 *
	 * fnSaveSessionValue
	 * Save $_SESSION ('', 'AccessLvl', 'main-table')
	 *
	 */	 	
	function fnSaveSessionValue ($sValue, $mName, $sParam='', $sApp='', $sWhat='', $bBackup=false) {
		
		global $sSUITE_NAME;
		
		if (!isset($_SESSION)) session_start();
		
		switch ($sParam) {
					
			case '' :
				if (is_string($mName)) { $_SESSION[$sSUITE_NAME][$mName] = $sValue; }
				break;

			case 'AccessLvl' :
				switch ($sWhat) {
					case 'app' :
						$_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat] = $sValue;
						break;					
					case 'table' :
						if ((is_array($mName) && isset($mName['sTable'])) || is_string($mName)) {
							$sName = (is_array($mName) && isset($mName['sTable']) ? $mName['sTable'] : (is_string($mName) ? $mName : ''));
							$_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName] = $sValue;
						}
						break;
					case 'viewitemlink' :
						if ((is_array($mName) && isset($mName['sViewItemLink'])) || is_string($mName)) {
							$sName = (is_array($mName) && isset($mName['sViewItemLink']) ? $mName['sViewItemLink'] : (is_string($mName) ? $mName : ''));
							$_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName] = $sValue;
						}
						break;						
					case 'tab' :
						if (is_array($mName) && isset($mName['sViewItemLink']) && isset($mName['sTab'])) {
							$_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']] = $sValue;
						}	
						break;	
					case 'field' :
						if (is_array($mName) && isset($mName['sViewItemLink']) && isset($mName['sTab']) && isset($mName['sField'])) {
							if ($bBackup) {
								$_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl']['aBackup'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']] = $sValue;		
							} else { 
								$_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']] = $sValue;
							}
						}
						break;	
				}
				break;	

			case 'main-table' :
				if (is_string($mName)) {
					if ($sWhat != '') {
						$_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$sWhat][$mName] = $sValue;
					} else {
						$_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$mName] = $sValue;					
					} 
				}
				break;
		}			
	}



	/**
	 *
	 * fnUnsetSessionValue
	 * Unset $_SESSION ('', 'AccessLvl', 'main-table')
	 *
	 */	 
	function fnUnsetSessionValue ($mName, $sParam='', $sApp='', $sWhat='', $bBackup=false) { // FIXME $mName
		
		global $sSUITE_NAME;
		
		switch ($sParam) {
						
			case '' :
				if (is_string($mName) && isset($_SESSION[$sSUITE_NAME][$mName])) {
					unset($_SESSION[$sSUITE_NAME][$mName]);
				}
				break;

			case 'AccessLvl' :
				switch ($sWhat) {
					case 'app' :
						if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat])) {
							unset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat]);
						}
					case 'table' :
						if ((is_array($mName) && isset($mName['sTable'])) || is_string($mName)) {
							$sName = (is_array($mName) && isset($mName['sTable']) ? $mName['sTable'] : (is_string($mName) ? $mName : ''));
							if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName]))
								unset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName]);
						}
						break;
					case 'viewitemlink' :
						if ((is_array($mName) && isset($mName['sViewItemLink'])) || is_string($mName)) {
							$sName = (is_array($mName) && isset($mName['sViewItemLink']) ? $mName['sViewItemLink'] : (is_string($mName) ? $mName : ''));
							if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName]))
								unset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$sName]);
						}
						break;						
					case 'tab' :
						if (is_array($mName) && isset($mName['sViewItemLink']) && isset($mName['sTab'])) {
							if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']]))
								unset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']]);
						}
						break;	
					case 'field' :
						if (is_array($mName) && isset($mName['sViewItemLink']) && isset($mName['sTab']) && isset($mName['sField'])) {
							if ($bBackup) {
								if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl']['aBackup'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']]))
									unset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl']['aBackup'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']]);		
							} else { 
								if (isset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']]))
									unset($_SESSION[$sSUITE_NAME][$sApp]['aAccessLvl'][$sWhat][$mName['sViewItemLink']][$mName['sTab']][$mName['sField']]);	
							}
						}
						break;	
				}
				break;	

			case 'main-table' :
				if ($sWhat != '') {
					if (isset($_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$sWhat][$mName])) {
						unset($_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$sWhat][$mName]);
					}
				} else {
					if (isset($_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$mName])) {
						unset($_SESSION[$sSUITE_NAME][$sApp]['aMainTable'][$mName]);
					}					
				} 	
				break;
		}
	}

	/**
	 *
	 * fnScriptOutput
	 * Viene utilizzata in table.php per capire qual è lo script iniziale in cui è stato
	 * incluso lo script 'table.php', e definire così qual è il risultato dello script.
	 *
	 */
	function fnScriptOutput ($sWhat, $sScript) {
		
		switch ($sWhat) {
			case 'table' :
				if ($sScript == 'index.php')
				return true;
				break;
			case 'excel' :
				if ($sScript == 'excel.php')
				return true;
				break;
			case 'json' :
				if ($sScript == 'json.php')
				return true;
				break;				
		}
		
		return false;
		
	}

	
	/**
	 *
	 * fnLastCheckView
	 *
	 */
	function fnLastCheckView ($sWhat, $iContratto) {
		
		$rResult = custom_mysql_query(fnLastCheckQuery($iContratto));
		if (mysql_num_rows($rResult) == 1) {
			$aRow = mysql_fetch_array($rResult);
		}		
		
		if (isset($aRow['iEsito']) && !empty($aRow['iEsito'])) {
			$sLastCheck = fnGetResourceProperties ($aRow['iEsito'], $sWhat, 'ESITO-CONTROLLO');
		} else {
			$sLastCheck = 'empty.png';
		}
		
		return $sLastCheck;
	}
	
	/**
	 *
	 * fnLastCheckQuery
	 *
	 */
	function fnLastCheckQuery ($iContratto=0) {

		global $iOK;		
		global $iATTESA_FINALE;
		global $iATTESA_SOLLECITO;
		
		$sQuery = " SELECT

			IF(`iEsitoFinale`!=0, `iEsitoFinale`, IF(`iEsitoSollecito`!=0, IF(`iEsitoSollecito`=$iOK, iEsitoSollecito, $iATTESA_FINALE), IF(`iEsitoVerifica`!=0, IF(`iEsitoVerifica`=$iOK, iEsitoVerifica, $iATTESA_SOLLECITO), 0))) AS `iEsito`, ".
			
			/*
			" sEsitoVerifica.sDescription AS sEsitoVerifica, sEsitoSollecito.sDescription AS sEsitoSollecito, sEsitoFinale.sDescription AS sEsitoFinale, ".
			" sReferenteVerifica.sDescription AS sReferenteVerifica, sReferenteSollecito.sDescription AS sReferenteSollecito, sReferenteSegnalazione.sDescription AS sReferenteSegnalazione, ".
			*/
			
			" `controlli`.*

			FROM `controlli`

			RIGHT JOIN (
			  SELECT `iContratto`, MAX(`dtVerifica`) AS `dtVerifica`
			  FROM (SELECT `iContratto`, `dtVerifica` FROM `controlli` WHERE `iTrash`=0) `elenco` 
			  GROUP BY `iContratto` ) `recenti` ON `recenti`.`iContratto`=`controlli`.`iContratto` AND `recenti`.`dtVerifica`=`controlli`.`dtVerifica` AND `controlli`.`iTrash`=0 ".
			
			/*
			" LEFT OUTER JOIN resources sEsitoVerifica ON sEsitoVerifica.id = controlli.iEsitoVerifica AND sEsitoVerifica.sType='ESITO-CONTROLLO'
			LEFT OUTER JOIN resources sEsitoSollecito ON sEsitoSollecito.id = controlli.iEsitoSollecito AND sEsitoVerifica.sType='ESITO-CONTROLLO'
			LEFT OUTER JOIN resources sEsitoFinale ON sEsitoFinale.id = controlli.iEsitoFinale AND sEsitoFinale.sType='ESITO-CONTROLLO' ".

			" LEFT OUTER JOIN resources sReferenteVerifica ON sReferenteVerifica.id = controlli.iReferenteVerifica AND sReferenteVerifica.sType='SIC'
			LEFT OUTER JOIN resources sReferenteSollecito ON sReferenteSollecito.id = controlli.iReferenteSollecito AND sReferenteSollecito.sType='SIC'
			LEFT OUTER JOIN resources sReferenteSegnalazione ON sReferenteSegnalazione.id = controlli.iReferenteSegnalazione AND sReferenteSegnalazione.sType='SIC' ".
			*/
			
			" WHERE `controlli`.`iTrash` = 0 ".(empty($iContratto) ? '' : " AND `controlli`.`iContratto` = $iContratto ")."
			
			GROUP BY `controlli`.`iContratto` ";
	
		return $sQuery;
		
	}
	
	/**
	 *
	 * fnTableDefault
	 * Se è definito un valore per $sMenuDefault (variabile $sTABLE_DEFAULT definita in const.inc.php)
	 * restituisce il valore contenuto in $sMenuDefault, altrimenti restituisce il primo elemento
	 * presente nell'array $aMenu (array $aTABLE definito in consst.inc.php).
	 *
	 */
	 
	function fnTableDefault ($sMenuDefault, $aMenu) { 
	
		$sTable = key($aMenu); // key($aMenu): restituisce il primo elemento dell'array '$aMenu'
		
		if (isset($sMenuDefault) && !empty($sMenuDefault) && isset($aMenu[$sMenuDefault])) { 
			$sTable = $sMenuDefault;
		}
		
		return $sTable;
	}


	/**
	 *
	 * fnCheckUsernameTypeDisplayClass
	 *
	 * Questa funzione è stata creata per essere usata in security.php e in security.json.php per
	 * capire quale icona è necessario visualizzare di fianco alla voce 'sUsername' (ovvero: 'gruppo',
	 * 'utente', 'errore', 'disabilitato'.
	 *
	 */
	function fnCheckUsernameTypeDisplayClass ($sUsername, $sType, $aUsers) {
		foreach ($aUsers as $aUser) {
			if ($aUser['sUsername'] == $sUsername and $aUser['sType'] == $sType) {
				if ($aUser['iEnabled'] == 1)
					return $aUser['sType'];
				else 
					return $aUser['sType'].' disabled';
			}
		} 
		return 'unknown';
	}

?>